Skip to content

Commit

Permalink
Fix ninja import of hashed passwords (MID-4764)
Browse files Browse the repository at this point in the history
Encryption of hashed password is now skipped during import.

This is a preliminary fix, though: there's the same issue when
importing users with hashed password via GUI. To be discussed yet.
  • Loading branch information
mederly committed Jun 26, 2018
1 parent 758192b commit 8a43fac
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 80 deletions.
Expand Up @@ -30,7 +30,6 @@
import com.evolveum.midpoint.prism.Itemable;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.PrismPropertyValue;
import com.evolveum.midpoint.prism.Visitable;
import com.evolveum.midpoint.prism.Visitor;
import com.evolveum.midpoint.prism.crypto.EncryptionException;
import com.evolveum.midpoint.prism.crypto.Protector;
Expand All @@ -47,6 +46,7 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.SmsConfigurationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SmsGatewayConfigurationType;
import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType;
import org.jetbrains.annotations.NotNull;

/**
* @author semancik
Expand All @@ -59,70 +59,59 @@ public class CryptoUtil {
/**
* Encrypts all encryptable values in the object.
*/
public static <T extends ObjectType> void encryptValues(final Protector protector, final PrismObject<T> object) throws EncryptionException{
Visitor visitor = new Visitor() {
@Override
public void visit(Visitable visitable){
if (!(visitable instanceof PrismPropertyValue)) {
return;
}
PrismPropertyValue<?> pval = (PrismPropertyValue<?>)visitable;
try {
encryptValue(protector, pval);
} catch (EncryptionException e) {
throw new TunnelException(e);
}
}
};
public static <T extends ObjectType> void encryptValues(Protector protector, PrismObject<T> object) throws EncryptionException {
encryptValues(protector, object, false);
}

public static <T extends ObjectType> void encryptValues(Protector protector, PrismObject<T> object, boolean skipHashed) throws EncryptionException {
try {
object.accept(visitor);
object.accept(createEncryptingVisitor(protector, skipHashed));
} catch (TunnelException e) {
EncryptionException origEx = (EncryptionException)e.getCause();
throw origEx;
throw (EncryptionException) e.getCause();
}
}

/**
* Encrypts all encryptable values in delta.
*/
public static <T extends ObjectType> void encryptValues(final Protector protector, final ObjectDelta<T> delta) throws EncryptionException{
Visitor visitor = new Visitor() {
@Override
public void visit(Visitable visitable){
if (!(visitable instanceof PrismPropertyValue)) {
return;
}
PrismPropertyValue<?> pval = (PrismPropertyValue<?>)visitable;
try {
encryptValue(protector, pval);
} catch (EncryptionException e) {
throw new TunnelException(e);
}
}
};
public static <T extends ObjectType> void encryptValues(Protector protector, ObjectDelta<T> delta) throws EncryptionException {
try {
delta.accept(visitor);
delta.accept(createEncryptingVisitor(protector, false));
} catch (TunnelException e) {
EncryptionException origEx = (EncryptionException)e.getCause();
throw origEx;
throw (EncryptionException) e.getCause();
}
}

private static <T extends ObjectType> void encryptValue(Protector protector, PrismPropertyValue<?> pval) throws EncryptionException{
@NotNull
private static Visitor createEncryptingVisitor(Protector protector, boolean skipHashed) {
return visitable -> {
if (!(visitable instanceof PrismPropertyValue)) {
return;
}
PrismPropertyValue<?> pval = (PrismPropertyValue<?>)visitable;
try {
encryptValue(protector, pval, skipHashed);
} catch (EncryptionException e) {
throw new TunnelException(e);
}
};
}

private static void encryptValue(Protector protector, PrismPropertyValue<?> pval, boolean skipHashed) throws EncryptionException{
Itemable item = pval.getParent();
if (item == null) {
return;
}
ItemDefinition itemDef = item.getDefinition();
if (itemDef == null || itemDef.getTypeName() == null) {
if (itemDef == null) {
return;
}

if (itemDef.getTypeName().equals(ProtectedStringType.COMPLEX_TYPE)) {
QName propName = item.getElementName();
PrismPropertyValue<ProtectedStringType> psPval = (PrismPropertyValue<ProtectedStringType>)pval;
ProtectedStringType ps = psPval.getValue();
encryptProtectedStringType(protector, ps, propName.getLocalPart());
encryptProtectedStringType(protector, ps, propName.getLocalPart(), skipHashed);
if (pval.getParent() == null){
pval.setParent(item);
}
Expand All @@ -131,26 +120,31 @@ private static <T extends ObjectType> void encryptValue(Protector protector, Pri
NotificationConfigurationType ncfg = ((PrismPropertyValue<NotificationConfigurationType>) pval).getValue();
if (ncfg.getMail() != null) {
for (MailServerConfigurationType mscfg : ncfg.getMail().getServer()) {
encryptProtectedStringType(protector, mscfg.getPassword(), "mail server password");
encryptProtectedStringType(protector, mscfg.getPassword(), "mail server password", skipHashed);
}
}
if (ncfg.getSms() != null) {
for (SmsConfigurationType smscfg : ncfg.getSms()) {
for (SmsGatewayConfigurationType gwcfg : smscfg.getGateway()) {
encryptProtectedStringType(protector, gwcfg.getPassword(), "sms gateway password");
encryptProtectedStringType(protector, gwcfg.getPassword(), "sms gateway password", skipHashed);
}
}
}
}
}

private static void encryptProtectedStringType(Protector protector, ProtectedStringType ps, String propName) throws EncryptionException {
private static void encryptProtectedStringType(Protector protector, ProtectedStringType ps, String propName,
boolean skipHashed) throws EncryptionException {
if (ps == null) {
return;
}

if (ps.isHashed()) {
throw new EncryptionException("Attempt to encrypt hashed value for "+propName);
if (skipHashed) {
return;
} else {
throw new EncryptionException("Attempt to encrypt hashed value for " + propName);
}
}
if (ps.getClearValue() != null) {
try {
Expand All @@ -163,18 +157,8 @@ private static void encryptProtectedStringType(Protector protector, ProtectedStr

// Checks that everything is encrypted
public static <T extends ObjectType> void checkEncrypted(final PrismObject<T> object) {
Visitor visitor = new Visitor() {
@Override
public void visit(Visitable visitable){
if (!(visitable instanceof PrismPropertyValue)) {
return;
}
PrismPropertyValue<?> pval = (PrismPropertyValue<?>)visitable;
checkEncrypted(pval);
}
};
try {
object.accept(visitor);
object.accept(createCheckingVisitor());
} catch (IllegalStateException e) {
throw new IllegalStateException(e.getMessage() + " in " + object, e);
}
Expand All @@ -183,30 +167,32 @@ public void visit(Visitable visitable){

// Checks that everything is encrypted
public static <T extends ObjectType> void checkEncrypted(final ObjectDelta<T> delta) {
Visitor visitor = new Visitor() {
@Override
public void visit(Visitable visitable){
if (!(visitable instanceof PrismPropertyValue)) {
return;
}
PrismPropertyValue<?> pval = (PrismPropertyValue<?>)visitable;
checkEncrypted(pval);
}
};
try {
delta.accept(visitor);
delta.accept(createCheckingVisitor());
} catch (IllegalStateException e) {
throw new IllegalStateException(e.getMessage() + " in delta " + delta, e);
}
}

private static <T extends ObjectType> void checkEncrypted(PrismPropertyValue<?> pval) {

@NotNull
private static Visitor createCheckingVisitor() {
return visitable -> {
if (!(visitable instanceof PrismPropertyValue)) {
return;
}
PrismPropertyValue<?> pval = (PrismPropertyValue<?>)visitable;
checkEncrypted(pval);
};
}

private static void checkEncrypted(PrismPropertyValue<?> pval) {
Itemable item = pval.getParent();
if (item == null) {
return;
}
ItemDefinition itemDef = item.getDefinition();
if (itemDef == null || itemDef.getTypeName() == null) {
if (itemDef == null) {
return;
}
if (itemDef.getTypeName().equals(ProtectedStringType.COMPLEX_TYPE)) {
Expand Down Expand Up @@ -239,15 +225,12 @@ private static <T extends ObjectType> void checkEncrypted(PrismPropertyValue<?>
}

public static void checkEncrypted(Collection<? extends ItemDelta> modifications) {
Visitor visitor = new Visitor() {
@Override
public void visit(Visitable visitable){
if (!(visitable instanceof PrismPropertyValue)) {
return;
}
PrismPropertyValue<?> pval = (PrismPropertyValue<?>)visitable;
checkEncrypted(pval);
Visitor visitor = visitable -> {
if (!(visitable instanceof PrismPropertyValue)) {
return;
}
PrismPropertyValue<?> pval = (PrismPropertyValue<?>)visitable;
checkEncrypted(pval);
};
for (ItemDelta<?,?> delta: modifications) {
try {
Expand Down Expand Up @@ -345,15 +328,15 @@ private static void securitySelfTestAlgorithm(String algorithmName, String trans
subresult.recordSuccess();
}
LOGGER.debug("Security self test (algorithmName={}, transformationName={}, keySize={}) success",
new Object[] {algorithmName, transformationName, keySize});
algorithmName, transformationName, keySize);
} catch (Throwable e) {
if (critical) {
LOGGER.error("Security self test (algorithmName={}, transformationName={}, keySize={}) failed: {}-{}",
new Object[] {algorithmName, transformationName, keySize, e.getMessage() ,e});
algorithmName, transformationName, keySize, e.getMessage(),e);
subresult.recordFatalError(e);
} else {
LOGGER.warn("Security self test (algorithmName={}, transformationName={}, keySize={}) failed: {}-{} (failure is expected in some cases)",
new Object[] {algorithmName, transformationName, keySize, e.getMessage() ,e});
algorithmName, transformationName, keySize, e.getMessage(),e);
subresult.recordWarning(e);
}
}
Expand Down
Expand Up @@ -58,7 +58,7 @@ public void run() {
RepoAddOptions opts = createRepoAddOptions(options);

if (!opts.isAllowUnencryptedValues()) {
CryptoUtil.encryptValues(protector, object);
CryptoUtil.encryptValues(protector, object, true);
}

RepositoryService repository = context.getRepository();
Expand Down

0 comments on commit 8a43fac

Please sign in to comment.