You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by jb...@apache.org on 2016/06/28 20:54:30 UTC

[1/2] karaf git commit: [KARAF-4533] Add kerberos login module

Repository: karaf
Updated Branches:
  refs/heads/karaf-4.0.x 303917453 -> 8b34b0ab3


[KARAF-4533] Add kerberos login module


Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/9ec0aea2
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/9ec0aea2
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/9ec0aea2

Branch: refs/heads/karaf-4.0.x
Commit: 9ec0aea205677eaab622b089fb68a6f94a87af4b
Parents: 3039174
Author: acartapanis <ac...@diginext.fr>
Authored: Fri May 20 10:40:53 2016 +0200
Committer: Jean-Baptiste Onofr� <jb...@apache.org>
Committed: Tue Jun 28 22:39:54 2016 +0200

----------------------------------------------------------------------
 jaas/modules/pom.xml                            |   8 +
 .../jaas/modules/krb5/Krb5LoginModule.java      |  65 +++
 .../jaas/modules/krb5/Krb5LoginModuleTest.java  | 420 +++++++++++++++++++
 .../developer-guide/security-framework.adoc     |  12 +
 4 files changed, 505 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/9ec0aea2/jaas/modules/pom.xml
----------------------------------------------------------------------
diff --git a/jaas/modules/pom.xml b/jaas/modules/pom.xml
index c4c03a5..bcccac4 100644
--- a/jaas/modules/pom.xml
+++ b/jaas/modules/pom.xml
@@ -131,6 +131,13 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.apache.directory.server</groupId>
+            <artifactId>apacheds-kerberos-test</artifactId>
+            <version>${directory-version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.apache.derby</groupId>
             <artifactId>derby</artifactId>
             <version>${derby-version}</version>
@@ -172,6 +179,7 @@
                             org.apache.wss4j.dom.message.token;resolution:=optional,
                             !net.sf.ehcache*,
                             !net.spy.memcached*,
+                            com.sun.security.auth.module;resolution:=optional,
                             *
                         </Import-Package>
                         <Private-Package>

http://git-wip-us.apache.org/repos/asf/karaf/blob/9ec0aea2/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/krb5/Krb5LoginModule.java
----------------------------------------------------------------------
diff --git a/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/krb5/Krb5LoginModule.java b/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/krb5/Krb5LoginModule.java
new file mode 100644
index 0000000..439f857
--- /dev/null
+++ b/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/krb5/Krb5LoginModule.java
@@ -0,0 +1,65 @@
+package org.apache.karaf.jaas.modules.krb5;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Karaf Kerberos login module.
+ */
+public class Krb5LoginModule implements LoginModule {
+
+    private com.sun.security.auth.module.Krb5LoginModule loginModule = new com.sun.security.auth.module.Krb5LoginModule();
+
+    @Override
+    public void initialize(Subject _subject, CallbackHandler _callbackHandler, Map<String, ?> _sharedState, Map<String, ?> _options) {
+        Map<String, Object> options = new HashMap<>(_options);
+        // interpolate system properties like ${karaf.etc} in options
+        for (Map.Entry<String, ?> entry : _options.entrySet()) {
+            if (entry.getValue() instanceof String) {
+                options.put(entry.getKey(), Krb5LoginModule.interpolate((String)entry.getValue()));
+            } else {
+                options.put(entry.getKey(), entry.getValue());
+            }
+        }
+        this.loginModule.initialize(_subject, _callbackHandler, _sharedState, options);
+    }
+
+    @Override
+    public boolean login() throws LoginException {
+        return loginModule.login();
+    }
+
+    @Override
+    public boolean commit() throws LoginException {
+        return loginModule.commit();
+    }
+
+    @Override
+    public boolean abort() throws LoginException {
+        return loginModule.abort();
+    }
+
+    @Override
+    public boolean logout() throws LoginException {
+        return loginModule.logout();
+    }
+
+    private static String interpolate(String _value) {
+        String value = _value;
+        Matcher matcher = Pattern.compile("\\$\\{([^}]+)\\}").matcher(value);
+        while (matcher.find()) {
+            String rep = System.getProperty(matcher.group(1));
+            if (rep != null) {
+                value = value.replace(matcher.group(0), rep);
+                matcher.reset(value);
+            }
+        }
+        return value;
+    }
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/9ec0aea2/jaas/modules/src/test/java/org/apache/karaf/jaas/modules/krb5/Krb5LoginModuleTest.java
----------------------------------------------------------------------
diff --git a/jaas/modules/src/test/java/org/apache/karaf/jaas/modules/krb5/Krb5LoginModuleTest.java b/jaas/modules/src/test/java/org/apache/karaf/jaas/modules/krb5/Krb5LoginModuleTest.java
new file mode 100644
index 0000000..a238837
--- /dev/null
+++ b/jaas/modules/src/test/java/org/apache/karaf/jaas/modules/krb5/Krb5LoginModuleTest.java
@@ -0,0 +1,420 @@
+package org.apache.karaf.jaas.modules.krb5;
+
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.SystemUtils;
+import org.apache.directory.api.ldap.model.constants.SupportedSaslMechanisms;
+import org.apache.directory.api.ldap.model.entry.DefaultEntry;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.util.Strings;
+import org.apache.directory.ldap.client.api.Krb5LoginConfiguration;
+import org.apache.directory.server.annotations.CreateKdcServer;
+import org.apache.directory.server.annotations.CreateLdapServer;
+import org.apache.directory.server.annotations.CreateTransport;
+import org.apache.directory.server.annotations.SaslMechanism;
+import org.apache.directory.server.core.annotations.ApplyLdifs;
+import org.apache.directory.server.core.annotations.ContextEntry;
+import org.apache.directory.server.core.annotations.CreateDS;
+import org.apache.directory.server.core.annotations.CreateIndex;
+import org.apache.directory.server.core.annotations.CreatePartition;
+import org.apache.directory.server.core.integ.FrameworkRunner;
+import org.apache.directory.server.core.kerberos.KeyDerivationInterceptor;
+import org.apache.directory.server.kerberos.kdc.AbstractKerberosITest;
+import org.apache.directory.server.kerberos.kdc.KerberosTestUtils;
+import org.apache.directory.server.kerberos.shared.crypto.encryption.KerberosKeyFactory;
+import org.apache.directory.server.kerberos.shared.keytab.Keytab;
+import org.apache.directory.server.kerberos.shared.keytab.KeytabEntry;
+import org.apache.directory.server.ldap.handlers.sasl.cramMD5.CramMd5MechanismHandler;
+import org.apache.directory.server.ldap.handlers.sasl.digestMD5.DigestMd5MechanismHandler;
+import org.apache.directory.server.ldap.handlers.sasl.gssapi.GssapiMechanismHandler;
+import org.apache.directory.server.ldap.handlers.sasl.ntlm.NtlmMechanismHandler;
+import org.apache.directory.server.ldap.handlers.sasl.plain.PlainMechanismHandler;
+import org.apache.directory.server.protocol.shared.transport.TcpTransport;
+import org.apache.directory.server.protocol.shared.transport.Transport;
+import org.apache.directory.shared.kerberos.KerberosTime;
+import org.apache.directory.shared.kerberos.KerberosUtils;
+import org.apache.directory.shared.kerberos.codec.types.EncryptionType;
+import org.apache.directory.shared.kerberos.components.EncryptionKey;
+import org.apache.directory.shared.kerberos.crypto.checksum.ChecksumType;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.kerberos.KerberosPrincipal;
+import javax.security.auth.kerberos.KerberosTicket;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginException;
+import java.io.File;
+import java.io.IOException;
+import java.security.Principal;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+@RunWith(FrameworkRunner.class)
+@CreateDS(name = "Krb5LoginModuleTest-class",
+        partitions =
+                {
+                        @CreatePartition(
+                                name = "example",
+                                suffix = "dc=example,dc=com",
+                                contextEntry = @ContextEntry(
+                                        entryLdif =
+                                                "dn: dc=example,dc=com\n" +
+                                                        "dc: example\n" +
+                                                        "objectClass: top\n" +
+                                                        "objectClass: domain\n\n"),
+                                indexes =
+                                        {
+                                                @CreateIndex(attribute = "objectClass"),
+                                                @CreateIndex(attribute = "dc"),
+                                                @CreateIndex(attribute = "ou")
+                                        })
+                },
+        additionalInterceptors =
+                {
+                        KeyDerivationInterceptor.class
+                })
+@CreateLdapServer(
+        transports =
+                {
+                        @CreateTransport(protocol = "LDAP")
+                },
+        saslHost = "localhost",
+        saslPrincipal = "ldap/localhost@EXAMPLE.COM",
+        saslMechanisms =
+                {
+                        @SaslMechanism(name = SupportedSaslMechanisms.PLAIN, implClass = PlainMechanismHandler.class),
+                        @SaslMechanism(name = SupportedSaslMechanisms.CRAM_MD5, implClass = CramMd5MechanismHandler.class),
+                        @SaslMechanism(name = SupportedSaslMechanisms.DIGEST_MD5, implClass = DigestMd5MechanismHandler.class),
+                        @SaslMechanism(name = SupportedSaslMechanisms.GSSAPI, implClass = GssapiMechanismHandler.class),
+                        @SaslMechanism(name = SupportedSaslMechanisms.NTLM, implClass = NtlmMechanismHandler.class),
+                        @SaslMechanism(name = SupportedSaslMechanisms.GSS_SPNEGO, implClass = NtlmMechanismHandler.class)
+                })
+@CreateKdcServer(
+        transports =
+                {
+                        @CreateTransport(protocol = "UDP", port = 6088),
+                        @CreateTransport(protocol = "TCP", port = 6088)
+                })
+@ApplyLdifs({
+        "dn: ou=users,dc=example,dc=com",
+        "objectClass: top",
+        "objectClass: organizationalUnit",
+        "ou: users"
+})
+public class Krb5LoginModuleTest extends AbstractKerberosITest {
+
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        // Set up a partition for EXAMPLE.COM and add user and service principals to test authentication with.
+        KerberosTestUtils.fixServicePrincipalName(
+                "ldap/" + KerberosTestUtils.getHostName() + "@EXAMPLE.COM", null, getLdapServer());
+        setupEnv(TcpTransport.class,
+                EncryptionType.AES128_CTS_HMAC_SHA1_96, ChecksumType.HMAC_SHA1_96_AES128);
+
+        kdcServer.getConfig().setPaEncTimestampRequired(false);
+        // Use our custom configuration to avoid reliance on external config
+        Configuration.setConfiguration(new Krb5LoginConfiguration());
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testKeytabSuccess() throws Exception {
+
+        Map<String, Object> props = new HashMap<>();
+        props.put("debug", "true");
+        props.put("useKeyTab", "true");
+        props.put("keyTab", createKeytab());
+        props.put("principal", "hnelson@EXAMPLE.COM");
+        props.put("doNotPrompt", "true");
+        props.put("storeKey", "true");
+        props.put("detailed.login.exception", "true");
+
+
+        Subject subject = new Subject();
+
+        Krb5LoginModule module = new Krb5LoginModule();
+        module.initialize(subject, null, null, props);
+
+        assertEquals("Precondition", 0, subject.getPrincipals().size());
+
+        Assert.assertTrue(module.login());
+        Assert.assertTrue(module.commit());
+
+        assertEquals(1, subject.getPrincipals().size());
+
+        boolean foundUser = false;
+        for (Principal pr : subject.getPrincipals()) {
+            if (pr instanceof KerberosPrincipal) {
+                assertEquals("hnelson@EXAMPLE.COM", pr.getName());
+                foundUser = true;
+                break;
+            }
+        }
+        assertTrue(foundUser);
+
+        boolean foundToken = false;
+        for (Object crd : subject.getPrivateCredentials()) {
+            if (crd instanceof KerberosTicket) {
+                assertEquals("hnelson@EXAMPLE.COM", ((KerberosTicket) crd).getClient().getName());
+                assertEquals("krbtgt/EXAMPLE.COM@EXAMPLE.COM", ((KerberosTicket) crd).getServer().getName());
+                foundToken = true;
+                break;
+            }
+        }
+        assertTrue(foundToken);
+
+        Assert.assertTrue(module.logout());
+
+    }
+
+    @Test(expected = LoginException.class)
+    public void testKeytabFailure() throws Exception {
+
+        Map<String, Object> props = new HashMap<>();
+        props.put("debug", "true");
+        props.put("useKeyTab", "true");
+        props.put("keyTab", createKeytab());
+        props.put("principal", "hnelson0@EXAMPLE.COM");
+        props.put("doNotPrompt", "true");
+        props.put("storeKey", "true");
+        props.put("detailed.login.exception", "true");
+
+
+        Subject subject = new Subject();
+
+        Krb5LoginModule module = new Krb5LoginModule();
+        module.initialize(subject, null, null, props);
+
+        assertEquals("Precondition", 0, subject.getPrincipals().size());
+
+        Assert.assertFalse(module.login());
+
+    }
+
+    @Test
+    public void testLoginSuccess() throws Exception {
+        CallbackHandler cb = new CallbackHandler() {
+            public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+                for (Callback cb : callbacks) {
+                    if (cb instanceof NameCallback) {
+                        ((NameCallback) cb).setName("hnelson");
+                    } else if (cb instanceof PasswordCallback) {
+                        ((PasswordCallback) cb).setPassword("secret".toCharArray());
+                    }
+                }
+            }
+        };
+        Subject subject = new Subject();
+
+        Krb5LoginModule module = new Krb5LoginModule();
+        module.initialize(subject, cb, null, new HashMap<String, Object>());
+
+        assertEquals("Precondition", 0, subject.getPrincipals().size());
+
+        Assert.assertTrue(module.login());
+        Assert.assertTrue(module.commit());
+
+        assertEquals(1, subject.getPrincipals().size());
+
+        boolean foundUser = false;
+        for (Principal pr : subject.getPrincipals()) {
+            if (pr instanceof KerberosPrincipal) {
+                assertEquals("hnelson@EXAMPLE.COM", pr.getName());
+                foundUser = true;
+                break;
+            }
+        }
+        assertTrue(foundUser);
+
+        boolean foundToken = false;
+        for (Object crd : subject.getPrivateCredentials()) {
+            if (crd instanceof KerberosTicket) {
+                assertEquals("hnelson@EXAMPLE.COM", ((KerberosTicket) crd).getClient().getName());
+                assertEquals("krbtgt/EXAMPLE.COM@EXAMPLE.COM", ((KerberosTicket) crd).getServer().getName());
+                foundToken = true;
+                break;
+            }
+        }
+        assertTrue(foundToken);
+
+        Assert.assertTrue(module.logout());
+
+    }
+
+    @Test(expected = LoginException.class)
+    public void testLoginUsernameFailure() throws Exception {
+        CallbackHandler cb = new CallbackHandler() {
+            public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+                for (Callback cb : callbacks) {
+                    if (cb instanceof NameCallback) {
+                        ((NameCallback) cb).setName("hnelson0");
+                    } else if (cb instanceof PasswordCallback) {
+                        ((PasswordCallback) cb).setPassword("secret".toCharArray());
+                    }
+                }
+            }
+        };
+        Subject subject = new Subject();
+
+        Krb5LoginModule module = new Krb5LoginModule();
+        module.initialize(subject, cb, null, new HashMap<String, Object>());
+
+        assertEquals("Precondition", 0, subject.getPrincipals().size());
+
+        Assert.assertFalse(module.login());
+
+    }
+
+    @Test(expected = LoginException.class)
+    public void testLoginPasswordFailure() throws Exception {
+        CallbackHandler cb = new CallbackHandler() {
+            public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+                for (Callback cb : callbacks) {
+                    if (cb instanceof NameCallback) {
+                        ((NameCallback) cb).setName("hnelson");
+                    } else if (cb instanceof PasswordCallback) {
+                        ((PasswordCallback) cb).setPassword("secret0".toCharArray());
+                    }
+                }
+            }
+        };
+        Subject subject = new Subject();
+
+        Krb5LoginModule module = new Krb5LoginModule();
+        module.initialize(subject, cb, null, new HashMap<String, Object>());
+
+        assertEquals("Precondition", 0, subject.getPrincipals().size());
+
+        Assert.assertFalse(module.login());
+
+    }
+
+    protected void setupEnv(Class<? extends Transport> transport, EncryptionType encryptionType,
+                            ChecksumType checksumType)
+            throws Exception {
+        // create krb5.conf with proper encryption type
+        String krb5confPath = createKrb5Conf(checksumType, encryptionType, transport == TcpTransport.class);
+        System.setProperty("java.security.krb5.conf", krb5confPath);
+
+        // change encryption type in KDC
+        kdcServer.getConfig().setEncryptionTypes(Collections.singleton(encryptionType));
+
+        // create principals
+        createPrincipal("uid=" + USER_UID, "Last", "First Last",
+                USER_UID, USER_PASSWORD, USER_UID + "@" + REALM);
+
+        createPrincipal("uid=krbtgt", "KDC Service", "KDC Service",
+                "krbtgt", "secret", "krbtgt/" + REALM + "@" + REALM);
+
+        String servicePrincipal = LDAP_SERVICE_NAME + "/" + HOSTNAME + "@" + REALM;
+        createPrincipal("uid=ldap", "Service", "LDAP Service",
+                "ldap", "randall", servicePrincipal);
+    }
+
+    private void createPrincipal(String rdn, String sn, String cn,
+                                 String uid, String userPassword, String principalName) throws LdapException {
+        Entry entry = new DefaultEntry();
+        entry.setDn(rdn + "," + USERS_DN);
+        entry.add("objectClass", "top", "person", "inetOrgPerson", "krb5principal", "krb5kdcentry");
+        entry.add("cn", cn);
+        entry.add("sn", sn);
+        entry.add("uid", uid);
+        entry.add("userPassword", userPassword);
+        entry.add("krb5PrincipalName", principalName);
+        entry.add("krb5KeyVersionNumber", "0");
+        conn.add(entry);
+    }
+
+    private String createKrb5Conf(ChecksumType checksumType, EncryptionType encryptionType, boolean isTcp) throws IOException {
+        File file = folder.newFile("krb5.conf");
+
+        String data = "";
+
+        data += "[libdefaults]" + SystemUtils.LINE_SEPARATOR;
+        data += "default_realm = " + REALM + SystemUtils.LINE_SEPARATOR;
+        data += "default_tkt_enctypes = " + encryptionType.getName() + SystemUtils.LINE_SEPARATOR;
+        data += "default_tgs_enctypes = " + encryptionType.getName() + SystemUtils.LINE_SEPARATOR;
+        data += "permitted_enctypes = " + encryptionType.getName() + SystemUtils.LINE_SEPARATOR;
+        //        data += "default_checksum = " + checksumType.getName() + SystemUtils.LINE_SEPARATOR;
+        //        data += "ap_req_checksum_type = " + checksumType.getName() + SystemUtils.LINE_SEPARATOR;
+        data += "default-checksum_type = " + checksumType.getName() + SystemUtils.LINE_SEPARATOR;
+
+        if (isTcp) {
+            data += "udp_preference_limit = 1" + SystemUtils.LINE_SEPARATOR;
+        }
+
+
+        data += "[realms]" + SystemUtils.LINE_SEPARATOR;
+        data += REALM + " = {" + SystemUtils.LINE_SEPARATOR;
+        data += "kdc = " + HOSTNAME + ":" + kdcServer.getTransports()[0].getPort() + SystemUtils.LINE_SEPARATOR;
+        data += "}" + SystemUtils.LINE_SEPARATOR;
+
+        data += "[domain_realm]" + SystemUtils.LINE_SEPARATOR;
+        data += "." + Strings.lowerCaseAscii(REALM) + " = " + REALM + SystemUtils.LINE_SEPARATOR;
+        data += Strings.lowerCaseAscii(REALM) + " = " + REALM + SystemUtils.LINE_SEPARATOR;
+
+        FileUtils.writeStringToFile(file, data);
+
+        return file.getAbsolutePath();
+    }
+
+    private KeytabEntry createKeytabEntry() throws ParseException {
+        String principalName = "hnelson@EXAMPLE.COM";
+        int principalType = 1;
+
+        String zuluTime = "20070217235745Z";
+        Date date = null;
+
+        synchronized (KerberosUtils.UTC_DATE_FORMAT) {
+            date = KerberosUtils.UTC_DATE_FORMAT.parse(zuluTime);
+        }
+
+        KerberosTime timeStamp = new KerberosTime(date.getTime());
+
+        byte keyVersion = 1;
+        String passPhrase = "secret";
+        Map<EncryptionType, EncryptionKey> keys = KerberosKeyFactory.getKerberosKeys(principalName, passPhrase);
+        EncryptionKey key = keys.get(EncryptionType.AES128_CTS_HMAC_SHA1_96);
+
+        return new KeytabEntry(principalName, principalType, timeStamp, keyVersion, key);
+    }
+
+    private String createKeytab() throws Exception {
+        File file = folder.newFile("test.keytab");
+
+        List<KeytabEntry> entries = new ArrayList<KeytabEntry>();
+
+        entries.add(createKeytabEntry());
+
+        Keytab writer = Keytab.getInstance();
+        writer.setEntries(entries);
+        writer.write(file);
+
+        return file.getAbsolutePath();
+    }
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/9ec0aea2/manual/src/main/asciidoc/developer-guide/security-framework.adoc
----------------------------------------------------------------------
diff --git a/manual/src/main/asciidoc/developer-guide/security-framework.adoc b/manual/src/main/asciidoc/developer-guide/security-framework.adoc
index 190d064..41d9ed7 100644
--- a/manual/src/main/asciidoc/developer-guide/security-framework.adoc
+++ b/manual/src/main/asciidoc/developer-guide/security-framework.adoc
@@ -505,6 +505,18 @@ The LDAPLoginModule doesn't provide backend engine. It means that the administra
 performed directly on the LDAP backend.
 ====
 
+===== KerberosLoginModule
+
+|===
+|LoginModule |BackendEngineFactory
+
+|org.apache.karaf.jaas.modules.krb5.Krb5LoginModule
+|
+|===
+
+The Kerberos login module uses the Oracle JVM Krb5 internal login module.
+
+
 ===== SyncopeLoginModule
 
 |===


[2/2] karaf git commit: [KARAF-4533] This closes #190

Posted by jb...@apache.org.
[KARAF-4533] This closes #190


Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/8b34b0ab
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/8b34b0ab
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/8b34b0ab

Branch: refs/heads/karaf-4.0.x
Commit: 8b34b0ab31abedc911f1ec9ff48f87ed3702a329
Parents: 3039174 9ec0aea
Author: Jean-Baptiste Onofr� <jb...@apache.org>
Authored: Tue Jun 28 22:53:51 2016 +0200
Committer: Jean-Baptiste Onofr� <jb...@apache.org>
Committed: Tue Jun 28 22:53:51 2016 +0200

----------------------------------------------------------------------
 jaas/modules/pom.xml                            |   8 +
 .../jaas/modules/krb5/Krb5LoginModule.java      |  65 +++
 .../jaas/modules/krb5/Krb5LoginModuleTest.java  | 420 +++++++++++++++++++
 .../developer-guide/security-framework.adoc     |  12 +
 4 files changed, 505 insertions(+)
----------------------------------------------------------------------