From 0476b3b66a3aec7f9fd2da3068d1bdad84d091bc Mon Sep 17 00:00:00 2001 From: "C. Alexander Leigh" Date: Thu, 16 Feb 2023 02:16:36 -0800 Subject: [PATCH] lc-esp-engine: Added CFG loading via environment. Refactored GDN API to use the Directory API. --- .../main/java/lc/esp/engine/Directory.java | 4 +++ .../main/java/lc/esp/engine/ESPEngine.java | 33 ++++++++++++++++--- .../main/java/lc/gdn/api/GdnApiService.java | 2 +- .../main/java/lc/gdn/api/TunnelIPHandler.java | 19 ++++++----- .../java/lc/mecha/aaa/ActiveDirectory.java | 15 +++------ .../lc/mecha/aaa/ActiveDirectoryConfig.java | 22 +++++++++++-- 6 files changed, 67 insertions(+), 28 deletions(-) diff --git a/java/lc-esp-engine/src/main/java/lc/esp/engine/Directory.java b/java/lc-esp-engine/src/main/java/lc/esp/engine/Directory.java index 3769d3849..fec50edef 100644 --- a/java/lc-esp-engine/src/main/java/lc/esp/engine/Directory.java +++ b/java/lc-esp-engine/src/main/java/lc/esp/engine/Directory.java @@ -40,4 +40,8 @@ public class Directory { ad.updatePassword(userId, oldPassword, newPassword); } + public Set findGroups(String userId) throws NamingException { + return ad.findGroups(userId); + } + } diff --git a/java/lc-esp-engine/src/main/java/lc/esp/engine/ESPEngine.java b/java/lc-esp-engine/src/main/java/lc/esp/engine/ESPEngine.java index 490403f25..020702cc0 100644 --- a/java/lc-esp-engine/src/main/java/lc/esp/engine/ESPEngine.java +++ b/java/lc-esp-engine/src/main/java/lc/esp/engine/ESPEngine.java @@ -3,27 +3,52 @@ package lc.esp.engine; import lc.mecha.aaa.ActiveDirectory; import lc.mecha.aaa.ActiveDirectoryConfig; import lc.mecha.fabric.LiteralMessageSubscription; +import lc.mecha.http.client.HttpUtil; import lc.mecha.http.server.PrefixedHandler; import lc.mecha.http.server.WebPipeline; import lc.mecha.http.server.WebServer; +import lc.mecha.json.JSONObject; import lc.mecha.lang.DangerousRunnable; import lc.mecha.log.MechaLogger; import lc.mecha.log.MechaLoggerFactory; import lc.mecha.util.UniversalJob; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; public class ESPEngine implements DangerousRunnable { private static final MechaLogger logger = MechaLoggerFactory.getLogger(ESPEngine.class); private final WebServer ws; private final Directory directory; + private final static String ENV_CFG = "LC_ESP_ENGINE_CFG"; + private final static String CFG_DIR_HOST = "dir_host"; + private final static String CFG_DIR_USER = "dir_username"; + private final static String CFG_DIR_PW = "dir_password"; + private final static String CFG_DIR_BASE = "dir_search_base"; + private final static String CFG_DIR_DOMAIN = "dir_domain"; public ESPEngine() throws Exception { ws = new WebServer(8080, 32); - ActiveDirectoryConfig cfg = new ActiveDirectoryConfig("gdn.leigh-co.com", - "ldaps://dc0.gdn.leigh-co.com", - "cn=users,dc=gdn,dc=leigh-co,dc=com"); + String cfgUrl = System.getenv(ENV_CFG); + if (cfgUrl == null) { + throw new Exception(ENV_CFG + " must be set."); + } - ActiveDirectory activeDirectory = new ActiveDirectory(cfg); + HttpClient httpClient = HttpUtil.makeOverlyTrustingClient(null); + HttpResponse response = httpClient.execute(new HttpGet(cfgUrl)); + HttpEntity entity = response.getEntity(); + JSONObject cfg = new JSONObject(entity.getContent()); + + ActiveDirectoryConfig dirCfg = new ActiveDirectoryConfig( + cfg.getString(CFG_DIR_DOMAIN), + cfg.getString(CFG_DIR_HOST), + cfg.getString(CFG_DIR_BASE), + cfg.getString(CFG_DIR_USER), + cfg.getString(CFG_DIR_PW)); + + ActiveDirectory activeDirectory = new ActiveDirectory(dirCfg); directory = new Directory(activeDirectory); } diff --git a/java/lc-gdn-api-svc/src/main/java/lc/gdn/api/GdnApiService.java b/java/lc-gdn-api-svc/src/main/java/lc/gdn/api/GdnApiService.java index 2af85c22d..c5bf1aea3 100644 --- a/java/lc-gdn-api-svc/src/main/java/lc/gdn/api/GdnApiService.java +++ b/java/lc-gdn-api-svc/src/main/java/lc/gdn/api/GdnApiService.java @@ -6,7 +6,7 @@ public class GdnApiService { public static void main(String[] args) throws Exception { ESPEngine engine = new ESPEngine(); - engine.register(new TunnelIPHandler()); + engine.register(new TunnelIPHandler(engine.getDirectory())); engine.register(new UserPasswordHandler(engine.getDirectory())); engine.register(new EchoHandler()); engine.runDangerously(); diff --git a/java/lc-gdn-api-svc/src/main/java/lc/gdn/api/TunnelIPHandler.java b/java/lc-gdn-api-svc/src/main/java/lc/gdn/api/TunnelIPHandler.java index c01cc0535..d014ea708 100644 --- a/java/lc-gdn-api-svc/src/main/java/lc/gdn/api/TunnelIPHandler.java +++ b/java/lc-gdn-api-svc/src/main/java/lc/gdn/api/TunnelIPHandler.java @@ -2,7 +2,7 @@ package lc.gdn.api; import jakarta.servlet.http.HttpServletResponse; import lc.cloudbox.cisco.CiscoController; -import lc.mecha.aaa.ActiveDirectory; +import lc.esp.engine.Directory; import lc.mecha.cred.Credential; import lc.mecha.fabric.HandlerStatus; import lc.mecha.http.client.HttpUtil; @@ -21,7 +21,6 @@ import java.net.InetAddress; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.HashMap; -import java.util.Map; import java.util.Set; /** @@ -45,10 +44,13 @@ public class TunnelIPHandler extends PrefixedHandler { private String gw0User, gw0Password, gw0Enable; private String gw3User, gw3Password, gw3Enable; + private final Directory dir; - public TunnelIPHandler() throws Exception { + public TunnelIPHandler(Directory dir) throws Exception { super(Set.of("/api/gdn/v1/ipsec/remote_ip")); + this.dir = dir; + String cfgUrl = System.getenv(ENV_CFG); if (cfgUrl == null) { throw new Exception(ENV_CFG + " must be set."); @@ -92,19 +94,18 @@ public class TunnelIPHandler extends PrefixedHandler { final String[] values = credentials.split(":", 2); // FIXME: Should be gdn.leigh-co.com, but the SSL certs don't have a altname for this. - ActiveDirectory ad = new ActiveDirectory("gdn.leigh-co.com", "ldaps://dc0.gdn.leigh-co.com", - "cn=users,dc=gdn,dc=leigh-co,dc=com"); - Map user = ad.authenticate(values[0], values[1]); - logger.info("AD returns: {}", user); - if (user == null) { + String userId = dir.authenticate(values[0], values[1]); + + logger.info("AD returns: {}", userId); + if (userId == null) { request.httpServletResponse.setHeader("WWW-Authenticate", "BASIC realm=\"LEIGH&CO\""); request.httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return HandlerStatus.BREAK; } - Set groups = ad.findGroups(); + Set groups = dir.findGroups(userId); InetAddress ipAddr = Inet4Address.getByName(request.httpServletRequest.getParameter("ip")); // Are we authorized? diff --git a/java/lc-mecha/src/main/java/lc/mecha/aaa/ActiveDirectory.java b/java/lc-mecha/src/main/java/lc/mecha/aaa/ActiveDirectory.java index 339882ed0..1ea1c4163 100644 --- a/java/lc-mecha/src/main/java/lc/mecha/aaa/ActiveDirectory.java +++ b/java/lc-mecha/src/main/java/lc/mecha/aaa/ActiveDirectory.java @@ -79,16 +79,17 @@ public final class ActiveDirectory { private final String searchBase; private String infoUser; private String infoPassword; - private String infoSid; public ActiveDirectory(ActiveDirectoryConfig svc) { - this(svc.getDomain(), svc.getLdapHost(), svc.getSearchBase()); + this(svc.getDomain(), svc.getLdapHost(), svc.getSearchBase(), svc.getUsername(), svc.getPassword()); } - public ActiveDirectory(final String domain, final String host, final String dn) { + public ActiveDirectory(final String domain, final String host, final String dn, final String un, final String pw) { this.domain = domain; this.ldapHost = host; this.searchBase = dn; + this.infoUser = un; + this.infoPassword = pw; trustSelfSignedSSL(); } @@ -260,14 +261,6 @@ public final class ActiveDirectory { '}'; } - /** - * Return all the groups that the current info user is a memeber of. This is the same as calling - * findGroups() with the info user's SID. - */ - public Set findGroups() throws NamingException { - return findGroups(infoSid); - } - /** * Return an enumeration of all the groups this given SID belongs to. This is the "correct" way to search for AD * group membership as it works via the tokenGroups attribute and will correctly determine diff --git a/java/lc-mecha/src/main/java/lc/mecha/aaa/ActiveDirectoryConfig.java b/java/lc-mecha/src/main/java/lc/mecha/aaa/ActiveDirectoryConfig.java index 0fe78be3f..1a9030652 100644 --- a/java/lc-mecha/src/main/java/lc/mecha/aaa/ActiveDirectoryConfig.java +++ b/java/lc-mecha/src/main/java/lc/mecha/aaa/ActiveDirectoryConfig.java @@ -7,10 +7,17 @@ public class ActiveDirectoryConfig { private final String ldapHost; private final String searchBase; - public ActiveDirectoryConfig(String domain, String ldapHost, String searchBase) { + + private final String username; + + private final String password; + + public ActiveDirectoryConfig(String domain, String ldapHost, String searchBase, String username, String password) { this.domain = domain; this.ldapHost = ldapHost; this.searchBase = searchBase; + this.username = username; + this.password = password; } public String getDomain() { @@ -30,11 +37,20 @@ public class ActiveDirectoryConfig { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ActiveDirectoryConfig that = (ActiveDirectoryConfig) o; - return Objects.equals(domain, that.domain) && Objects.equals(ldapHost, that.ldapHost) && Objects.equals(searchBase, that.searchBase); + return Objects.equals(domain, that.domain) && Objects.equals(ldapHost, that.ldapHost) && Objects.equals(searchBase, that.searchBase) && Objects.equals(username, that.username) && Objects.equals(password, that.password); } @Override public int hashCode() { - return Objects.hash(domain, ldapHost, searchBase); + return Objects.hash(domain, ldapHost, searchBase, username, password); + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; } + } -- GitLab