Skip to content

Commit

Permalink
Make LdapSettingsService#load() return null in case of wrong password…
Browse files Browse the repository at this point in the history
… secret (#2178)

Fixes #2176
  • Loading branch information
joschi authored and dennisoelkers committed May 4, 2016
1 parent 4d890cc commit c2a6eaa
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 11 deletions.
Expand Up @@ -20,13 +20,15 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nullable;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AESTools {
private static final Logger LOG = LoggerFactory.getLogger(AESTools.class);

@Nullable
public static String encrypt(String plainText, String encryptionKey, String salt) {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/ISO10126Padding", "SunJCE");
Expand All @@ -36,9 +38,10 @@ public static String encrypt(String plainText, String encryptionKey, String salt
} catch (Exception e) {
LOG.error("Could not encrypt value.", e);
}
return null;
return null;
}

@Nullable
public static String decrypt(String cipherText, String encryptionKey, String salt) {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/ISO10126Padding", "SunJCE");
Expand All @@ -50,5 +53,4 @@ public static String decrypt(String cipherText, String encryptionKey, String sal
}
return null;
}

}
Expand Up @@ -19,10 +19,10 @@
import org.graylog2.plugin.database.PersistedService;
import org.graylog2.shared.security.ldap.LdapSettings;

/**
* @author Dennis Oelkers <dennis@torch.sh>
*/
import javax.annotation.Nullable;

public interface LdapSettingsService extends PersistedService {
@Nullable
LdapSettings load();

void delete();
Expand Down
Expand Up @@ -25,6 +25,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nullable;
import javax.inject.Inject;
import java.util.List;

Expand All @@ -39,9 +40,9 @@ public LdapSettingsServiceImpl(MongoConnection mongoConnection, LdapSettingsImpl
}

@Override
@Nullable
public LdapSettings load() {
DBObject query = new BasicDBObject();
final List<DBObject> results = query(LdapSettingsImpl.class, query);
final List<DBObject> results = query(LdapSettingsImpl.class, new BasicDBObject());
if (results.size() == 0) {
return null;
}
Expand All @@ -51,13 +52,16 @@ public LdapSettings load() {
results.size());
return null;
}
final DBObject settingsObject = results.get(0);
return ldapSettingsFactory.create((ObjectId) settingsObject.get("_id"), settingsObject.toMap());
final DBObject settings = results.get(0);
final LdapSettingsImpl ldapSettings = ldapSettingsFactory.create((ObjectId) settings.get("_id"), settings.toMap());
if (null == ldapSettings.getSystemPassword()) {
return null;
}
return ldapSettings;
}

@Override
public void delete() {
DBObject query = new BasicDBObject();
destroyAll(LdapSettingsImpl.class, query);
destroyAll(LdapSettingsImpl.class);
}
}
@@ -0,0 +1,119 @@
/**
* This file is part of Graylog.
*
* Graylog is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Graylog 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 Graylog. If not, see <http://www.gnu.org/licenses/>.
*/
package org.graylog2.security.ldap;

import com.lordofthejars.nosqlunit.annotation.UsingDataSet;
import com.lordofthejars.nosqlunit.core.LoadStrategyEnum;
import com.lordofthejars.nosqlunit.mongodb.InMemoryMongoDb;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import org.bson.types.ObjectId;
import org.graylog2.Configuration;
import org.graylog2.database.MongoConnectionRule;
import org.graylog2.shared.security.ldap.LdapSettings;
import org.graylog2.users.RoleService;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

import java.net.URI;
import java.util.Map;

import static com.lordofthejars.nosqlunit.mongodb.InMemoryMongoDb.InMemoryMongoRuleBuilder.newInMemoryMongoDbRule;
import static org.assertj.core.api.Assertions.assertThat;

public class LdapSettingsServiceImplTest {
@ClassRule
public static final InMemoryMongoDb IN_MEMORY_MONGO_DB = newInMemoryMongoDbRule().build();

@Rule
public final MongoConnectionRule mongoRule = MongoConnectionRule.build("test");

@Rule
public final MockitoRule mockitoRule = MockitoJUnit.rule();

private final Configuration configuration = new Configuration() {
@Override
public String getPasswordSecret() {
return "asdfasdfasdfasdfasdf";
}
};
private final LdapSettingsImpl.Factory factory = new LdapSettingsImpl.Factory() {
@Override
public LdapSettingsImpl createEmpty() {
return new LdapSettingsImpl(configuration, roleService);
}

@Override
public LdapSettingsImpl create(ObjectId objectId, Map<String, Object> fields) {
return new LdapSettingsImpl(configuration, roleService, objectId, fields);
}
};

@Mock
private RoleService roleService;
private LdapSettingsServiceImpl ldapSettingsService;

@Before
public void setUp() throws Exception {
ldapSettingsService = new LdapSettingsServiceImpl(mongoRule.getMongoConnection(), factory);
}

@Test
@UsingDataSet(loadStrategy = LoadStrategyEnum.CLEAN_INSERT)
public void loadReturnsLdapSettings() throws Exception {
final LdapSettings ldapSettings = ldapSettingsService.load();
assertThat(ldapSettings).isNotNull();
assertThat(ldapSettings.getId()).isEqualTo("54e3deadbeefdeadbeefaffe");
assertThat(ldapSettings.getUri()).isEqualTo(URI.create("ldap://localhost:389"));
assertThat(ldapSettings.getSystemPassword()).isEqualTo("password");
}

@Test
@UsingDataSet(loadStrategy = LoadStrategyEnum.CLEAN_INSERT, locations = "LdapSettingsServiceImplTest-invalid-password.json")
public void loadReturnNullIfPasswordSecretIsWrong() throws Exception {
final LdapSettings ldapSettings = ldapSettingsService.load();
assertThat(ldapSettings).isNull();
}

@Test
@UsingDataSet(loadStrategy = LoadStrategyEnum.DELETE_ALL)
public void loadReturnsNullIfDatabaseIsEmpty() throws Exception {
assertThat(ldapSettingsService.load()).isNull();
}

@Test
@UsingDataSet(loadStrategy = LoadStrategyEnum.DELETE_ALL)
public void loadReturnsNullIfDatabaseHasMoreThanOneEntry() throws Exception {
final DBCollection collection = mongoRule.getMongoConnection().getDatabase().getCollection("ldap_settings");
collection.insert(new BasicDBObject("foo", "bar"), new BasicDBObject("quux", "baz"));
assertThat(ldapSettingsService.load()).isNull();
}

@Test
@UsingDataSet(loadStrategy = LoadStrategyEnum.CLEAN_INSERT)
public void deleteRemovesAllLdapSettings() throws Exception {
final DBCollection collection = mongoRule.getMongoConnection().getDatabase().getCollection("ldap_settings");
assertThat(collection.count()).isEqualTo(1L);
ldapSettingsService.delete();
assertThat(collection.count()).isEqualTo(0);
}
}
@@ -0,0 +1,26 @@
{
"ldap_settings": [
{
"_id": {
"$oid": "54e3deadbeefdeadbeefaffe"
},
"use_start_tls": false,
"system_password": "deadbeefcafebabe12345678deadbeef",
"principal_search_pattern": "(&(objectClass=inetOrgPerson)(uid={0}))",
"username_attribute": "cn",
"system_password_salt": "455f07a629b2d830",
"system_username": "uid=admin,ou=system",
"trust_all_certificates": false,
"group_search_base": "cn=users,dc=example,dc=com",
"default_group": "55ce0ae8c02622ddd63de149",
"group_search_pattern": "(objectClass=groupOfNames)",
"active_directory": false,
"enabled": true,
"group_id_attribute": "cn",
"search_base": "cn=users,dc=example,dc=com",
"group_role_mapping_list": [
],
"ldap_uri": "ldap://localhost:389"
}
]
}
@@ -0,0 +1,26 @@
{
"ldap_settings": [
{
"_id": {
"$oid": "54e3deadbeefdeadbeefaffe"
},
"use_start_tls": false,
"system_password": "0ebc21625f0e65ee36adb65e0448703a",
"principal_search_pattern": "(&(objectClass=inetOrgPerson)(uid={0}))",
"username_attribute": "cn",
"system_password_salt": "455f07a629b2d830",
"system_username": "uid=admin,ou=system",
"trust_all_certificates": false,
"group_search_base": "cn=users,dc=example,dc=com",
"default_group": "55ce0ae8c02622ddd63de149",
"group_search_pattern": "(objectClass=groupOfNames)",
"active_directory": false,
"enabled": true,
"group_id_attribute": "cn",
"search_base": "cn=users,dc=example,dc=com",
"group_role_mapping_list": [
],
"ldap_uri": "ldap://localhost:389"
}
]
}

0 comments on commit c2a6eaa

Please sign in to comment.