diff --git a/common/src/main/java/com/genexus/util/Encryption.java b/common/src/main/java/com/genexus/util/Encryption.java index 378130108..5ac6b8472 100644 --- a/common/src/main/java/com/genexus/util/Encryption.java +++ b/common/src/main/java/com/genexus/util/Encryption.java @@ -148,10 +148,40 @@ public static String decrypt16(String value, String key) return ""; } - public static String decrypt64(String value){ - value= decrypt64(value, SpecificImplementation.Application.getModelContext().getServerKey()); - return value.substring(0, value.length()-CHECKSUM_LENGTH); - } + public static String decrypt64(String value){ + value = decrypt64(value, SpecificImplementation.Application.getModelContext().getServerKey()); + return value.substring(0, value.length()-CHECKSUM_LENGTH); + } + + /** + * Returns decrpyted value if the checksum verification succedes. Otherwise, original value is returned + * @param encryptedOrDecryptedValue + * @return Decrypted Value + */ + public static String tryDecrypt64(String encryptedOrDecryptedValue) { + return tryDecrypt64(encryptedOrDecryptedValue, SpecificImplementation.Application.getModelContext().getServerKey()); + } + + public static String tryDecrypt64(String encryptedOrDecryptedValue, String key) { + if (encryptedOrDecryptedValue == null) { + return null; + } + + int checkSumLength = Encryption.getCheckSumLength(); + if (encryptedOrDecryptedValue.length() > checkSumLength) { + String dec = Encryption.decrypt64(encryptedOrDecryptedValue, key); + // Ojo, el = de aca es porque sino no me deja tener passwords vacias, dado que el length queda igual al length del checksum + if (dec.length() >= checkSumLength) { + String checksum = CommonUtil.right(dec, checkSumLength); + String decryptedValue = CommonUtil.left(dec, dec.length() - checkSumLength); + if (checksum.equals(Encryption.checksum(decryptedValue, Encryption.getCheckSumLength()))) { + return decryptedValue; + } + } + } + return encryptedOrDecryptedValue; + } + public static String decrypt64(String value, String key) { @@ -193,7 +223,9 @@ public static String decrypt64(String value, String key, boolean safeEncoding) return ""; } } - + + + private static final int CHECKSUM_LENGTH = 6; public static int getCheckSumLength() diff --git a/common/src/main/java/com/genexus/util/GXService.java b/common/src/main/java/com/genexus/util/GXService.java index ac9217b81..21e015ce6 100644 --- a/common/src/main/java/com/genexus/util/GXService.java +++ b/common/src/main/java/com/genexus/util/GXService.java @@ -6,8 +6,13 @@ public class GXService private String type; private String className; private boolean allowMultiple; + private boolean allowOverrideWithEnvVarSettings; private GXProperties properties; - + + public GXService() { + this.allowOverrideWithEnvVarSettings = true; + } + public String getName() { return name; @@ -42,12 +47,22 @@ public boolean getAllowMultiple() { return allowMultiple; } - + public void setAllowMultiple(boolean allowMultiple) { this.allowMultiple = allowMultiple; } - + + public void setAllowOverrideWithEnvVarSettings(boolean allowOverride) + { + this.allowOverrideWithEnvVarSettings = allowOverride; + } + + public boolean getAllowOverrideWithEnvVarSettings() + { + return allowOverrideWithEnvVarSettings; + } + public GXProperties getProperties() { return properties; diff --git a/gxexternalproviders/src/main/java/com/genexus/db/driver/ExternalProviderBase.java b/gxexternalproviders/src/main/java/com/genexus/db/driver/ExternalProviderBase.java index c24ec35f9..775877765 100644 --- a/gxexternalproviders/src/main/java/com/genexus/db/driver/ExternalProviderBase.java +++ b/gxexternalproviders/src/main/java/com/genexus/db/driver/ExternalProviderBase.java @@ -27,7 +27,6 @@ public ExternalProviderBase() { init(); } - public ExternalProviderBase(GXService s) { this.service = s; init(); @@ -51,16 +50,18 @@ public String getEncryptedPropertyValue(String propertyName, String alternativeP } public String getEncryptedPropertyValue(String propertyName, String alternativePropertyName, String defaultValue) { - String value = getPropertyValue(propertyName, alternativePropertyName, defaultValue); - if (value != null && value.length() > 0) { + String encryptedOrUnEncryptedValue = getPropertyValue(propertyName, alternativePropertyName, defaultValue); + String decryptedValue = encryptedOrUnEncryptedValue; + if (encryptedOrUnEncryptedValue != null && encryptedOrUnEncryptedValue.length() > 0) { try { - value = Encryption.decrypt64(value); + String decryptedTemp = Encryption.tryDecrypt64(encryptedOrUnEncryptedValue); + decryptedValue = (decryptedTemp != null) ? decryptedTemp: encryptedOrUnEncryptedValue; } catch (Exception e) { logger.warn("Could not decrypt property name: " + resolvePropertyName(propertyName)); } } - return value; + return decryptedValue; } public String getPropertyValue(String propertyName, String alternativePropertyName) throws Exception{ @@ -74,13 +75,13 @@ public String getPropertyValue(String propertyName, String alternativePropertyNa } public String getPropertyValue(String propertyName, String alternativePropertyName, String defaultValue) { - propertyName = resolvePropertyName(propertyName); - String value = System.getenv(propertyName); - if (value == null || value.length() == 0){ - value = System.getenv(alternativePropertyName); + String value = readFromEnvVars(propertyName, alternativePropertyName); + if (value != null) { + return value; } - if (this.service != null) { - value = this.service.getProperties().get(propertyName); + String resolvedPtyName = resolvePropertyName(propertyName); + if (service != null) { + value = this.service.getProperties().get(resolvedPtyName); if (value == null || value.length() == 0) { value = this.service.getProperties().get(alternativePropertyName); } @@ -88,6 +89,18 @@ public String getPropertyValue(String propertyName, String alternativePropertyNa return value != null? value: defaultValue; } + private String readFromEnvVars(String propertyName, String alternativePropertyName) { + if (service != null && !service.getAllowOverrideWithEnvVarSettings()){ + return null; + } + + String value = System.getenv(resolvePropertyName(propertyName)); + if (value == null){ + value = System.getenv(alternativePropertyName); + } + return value; + } + private String resolvePropertyName(String propertyName) { return String.format("STORAGE_%s_%s", getName(), propertyName); } diff --git a/gxexternalproviders/src/main/java/com/genexus/db/driver/ExternalProviderS3.java b/gxexternalproviders/src/main/java/com/genexus/db/driver/ExternalProviderS3.java index 865d0bb69..4e4d70a92 100644 --- a/gxexternalproviders/src/main/java/com/genexus/db/driver/ExternalProviderS3.java +++ b/gxexternalproviders/src/main/java/com/genexus/db/driver/ExternalProviderS3.java @@ -1,5 +1,6 @@ package com.genexus.db.driver; +import com.amazonaws.auth.*; import com.amazonaws.client.builder.AwsClientBuilder; import com.amazonaws.services.s3.model.*; import com.amazonaws.services.s3.AmazonS3ClientBuilder; @@ -14,9 +15,7 @@ import java.io.File; import java.io.InputStream; import java.io.ByteArrayInputStream; -import com.amazonaws.auth.AWSCredentials; -import com.amazonaws.auth.BasicAWSCredentials; -import com.amazonaws.auth.AWSStaticCredentialsProvider; + import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.util.IOUtils; @@ -41,6 +40,7 @@ public class ExternalProviderS3 extends ExternalProviderBase implements External static final String STORAGE_ENDPOINT = "ENDPOINT"; static final String BUCKET = "BUCKET_NAME"; static final String REGION = "REGION"; + static final String USE_IAM = "USE_IAM"; //Keep it for compatibility reasons @Deprecated @@ -90,8 +90,8 @@ public ExternalProviderS3(GXService providerService) throws Exception{ } private void initialize() throws Exception{ - String accessKey = getEncryptedPropertyValue(ACCESS_KEY, ACCESS_KEY_ID_DEPRECATED); - String secretKey = getEncryptedPropertyValue(SECRET_ACCESS_KEY, SECRET_ACCESS_KEY_DEPRECATED); + String accessKey = getEncryptedPropertyValue(ACCESS_KEY, ACCESS_KEY_ID_DEPRECATED, ""); + String secretKey = getEncryptedPropertyValue(SECRET_ACCESS_KEY, SECRET_ACCESS_KEY_DEPRECATED, ""); String bucket = getEncryptedPropertyValue(BUCKET, BUCKET_DEPRECATED); String folder = getPropertyValue(FOLDER, FOLDER_DEPRECATED, ""); String region = getPropertyValue(REGION, REGION_DEPRECATED, DEFAULT_REGION); @@ -109,10 +109,11 @@ private void initialize() throws Exception{ if (region.length() == 0) { region = DEFAULT_REGION; } + this.bucket = bucket; this.folder = folder; - this.client = buildS3Client(accessKey, secretKey, endpointValue, region); + this.client = buildS3Client(accessKey, secretKey, endpointValue, region); bucketExists(); ensureFolder(folder); } @@ -120,8 +121,16 @@ private void initialize() throws Exception{ private AmazonS3 buildS3Client(String accessKey, String secretKey, String endpoint, String region) { AmazonS3 s3Client; - AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey); - AmazonS3ClientBuilder builder = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(credentials)); + + boolean bUseIAM = !getPropertyValue(USE_IAM, "", "").isEmpty() || (accessKey.equals("") && secretKey.equals("")); + + AmazonS3ClientBuilder builder = bUseIAM ? + AmazonS3ClientBuilder.standard(): + AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey))); + + if (bUseIAM) { + logger.debug("Using IAM Credentials"); + } if (endpoint.length() > 0 && !endpoint.contains(".amazonaws.com")) { pathStyleUrls = true; diff --git a/java/src/main/java/com/genexus/Application.java b/java/src/main/java/com/genexus/Application.java index 0fd045916..d982b4376 100644 --- a/java/src/main/java/com/genexus/Application.java +++ b/java/src/main/java/com/genexus/Application.java @@ -177,15 +177,23 @@ private static ExternalProvider getExternalProviderImpl(String service) GXService providerService = getGXServices().get(service); if (providerService != null) { + Class providerClass; try { - Class providerClass = Class.forName(providerService.getClassName()); + providerClass = Class.forName(providerService.getClassName()); + } + catch (ClassNotFoundException e) + { + logger.fatal("Unrecognized External Provider class (ClassNotFound) : " + providerService.getName() + " / " + providerService.getClassName(), e); + throw new InternalError("Unrecognized External Provider class (ClassNotFound) : " + providerService.getName() + " / " + providerService.getClassName()); + } + try { externalProviderImpl = (ExternalProvider) providerClass.getConstructor(String.class).newInstance(service); } catch (Exception e) { - logger.error("Unrecognized External Provider class : " + providerService.getName() + " / " + providerService.getClassName(), e); - throw new InternalError("Unrecognized External Provider class : " + providerService.getName() + " / " + providerService.getClassName()); + logger.fatal("Unable to Initialize External Provider Class: " + providerService.getClassName(), e); + throw new InternalError("Unable to Initialize External Provider Class: " + providerService.getClassName(), e); } } return externalProviderImpl; diff --git a/java/src/main/java/com/genexus/configuration/ExternalStorage.java b/java/src/main/java/com/genexus/configuration/ExternalStorage.java index 32fa85db4..ce6cd51ae 100644 --- a/java/src/main/java/com/genexus/configuration/ExternalStorage.java +++ b/java/src/main/java/com/genexus/configuration/ExternalStorage.java @@ -37,7 +37,7 @@ public boolean create(String name, GXProperties properties, GXStorageProvider[] if (isNullOrEmpty(name)) { - GXutil.ErrorToMessages("Unsopported", "Provider cannot be empty", messages[0]); + GXutil.ErrorToMessages("Unsupported", "Provider name cannot be empty", messages[0]); return false; } @@ -49,6 +49,7 @@ public boolean create(String name, GXProperties properties, GXStorageProvider[] providerService.setType(GXServices.STORAGE_SERVICE); providerService.setName(name); providerService.setAllowMultiple(false); + providerService.setAllowOverrideWithEnvVarSettings(false); providerService.setProperties(new GXProperties()); }