org.apache.ambari.server.serveraction.kerberos.KerberosOperationHandlerTest.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.ambari.server.serveraction.kerberos.KerberosOperationHandlerTest.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.ambari.server.serveraction.kerberos;

import junit.framework.Assert;
import org.apache.commons.codec.binary.Base64;
import org.apache.directory.server.kerberos.shared.keytab.Keytab;
import org.apache.directory.server.kerberos.shared.keytab.KeytabEntry;
import org.apache.directory.shared.kerberos.codec.types.EncryptionType;
import org.easymock.EasyMockSupport;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.io.File;
import java.io.FileInputStream;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public abstract class KerberosOperationHandlerTest extends EasyMockSupport {

    @Rule
    public TemporaryFolder folder = new TemporaryFolder();

    @Test
    public void testCreateSecurePassword() throws Exception {

        KerberosOperationHandler handler1 = createHandler();
        KerberosOperationHandler handler2 = createHandler();

        String password1 = handler1.createSecurePassword();
        Assert.assertNotNull(password1);
        Assert.assertEquals(KerberosOperationHandler.SECURE_PASSWORD_LENGTH, password1.length());

        String password2 = handler2.createSecurePassword();
        Assert.assertNotNull(password2);
        Assert.assertEquals(KerberosOperationHandler.SECURE_PASSWORD_LENGTH, password2.length());

        // Make sure the passwords are different... if they are the same, that indicated the random
        // number generators are generating using the same pattern and that is not secure.
        Assert.assertFalse((password1.equals(password2)));
    }

    @Test
    public void testCreateSecurePasswordWithSize() throws Exception {
        KerberosOperationHandler handler = createHandler();

        String password;

        password = handler.createSecurePassword(10);
        Assert.assertNotNull(password);
        Assert.assertEquals(10, password.length());

        password = handler.createSecurePassword(0);
        Assert.assertNotNull(password);
        Assert.assertEquals(KerberosOperationHandler.SECURE_PASSWORD_LENGTH, password.length());

        password = handler.createSecurePassword(-20);
        Assert.assertNotNull(password);
        Assert.assertEquals(KerberosOperationHandler.SECURE_PASSWORD_LENGTH, password.length());
    }

    @Test
    public void testCreateKeytabFileOneAtATime() throws Exception {
        KerberosOperationHandler handler = createHandler();
        File file = folder.newFile();
        final String principal1 = "principal1@REALM.COM";
        final String principal2 = "principal2@REALM.COM";
        int count;

        Assert.assertTrue(handler.createKeytabFile(principal1, handler.createSecurePassword(), 0, file));

        Keytab keytab = Keytab.read(file);
        Assert.assertNotNull(keytab);

        List<KeytabEntry> entries = keytab.getEntries();
        Assert.assertNotNull(entries);
        Assert.assertFalse(entries.isEmpty());

        count = entries.size();

        for (KeytabEntry entry : entries) {
            Assert.assertEquals(principal1, entry.getPrincipalName());
        }

        Assert.assertTrue(handler.createKeytabFile(principal2, handler.createSecurePassword(), 0, file));

        keytab = Keytab.read(file);
        Assert.assertNotNull(keytab);

        entries = keytab.getEntries();
        Assert.assertNotNull(entries);
        Assert.assertFalse(entries.isEmpty());

        Assert.assertEquals(count * 2, entries.size());
    }

    @Test
    public void testEnsureKeytabFileContainsNoDuplicates() throws Exception {
        KerberosOperationHandler handler = createHandler();
        File file = folder.newFile();
        final String principal1 = "principal1@REALM.COM";
        final String principal2 = "principal2@REALM.COM";
        Set<String> seenEntries = new HashSet<String>();

        Assert.assertTrue(handler.createKeytabFile(principal1, handler.createSecurePassword(), 0, file));
        Assert.assertTrue(handler.createKeytabFile(principal2, handler.createSecurePassword(), 0, file));

        // Attempt to add duplicate entries
        Assert.assertTrue(handler.createKeytabFile(principal2, handler.createSecurePassword(), 0, file));

        Keytab keytab = Keytab.read(file);
        Assert.assertNotNull(keytab);

        List<KeytabEntry> entries = keytab.getEntries();
        Assert.assertNotNull(entries);
        Assert.assertFalse(entries.isEmpty());

        for (KeytabEntry entry : entries) {
            String seenEntry = String.format("%s|%s", entry.getPrincipalName(),
                    entry.getKey().getKeyType().toString());
            Assert.assertFalse(seenEntries.contains(seenEntry));
            seenEntries.add(seenEntry);
        }
    }

    @Test
    public void testCreateKeytabFileExceptions() throws Exception {
        KerberosOperationHandler handler = createHandler();
        File file = folder.newFile();
        final String principal1 = "principal1@REALM.COM";

        try {
            handler.createKeytabFile(null, handler.createSecurePassword(), 0, file);
            Assert.fail("KerberosOperationException not thrown with null principal");
        } catch (Throwable t) {
            Assert.assertEquals(KerberosOperationException.class, t.getClass());
        }

        try {
            handler.createKeytabFile(principal1, null, null, file);
            Assert.fail("KerberosOperationException not thrown with null password");
        } catch (Throwable t) {
            Assert.assertEquals(KerberosOperationException.class, t.getClass());
        }

        try {
            handler.createKeytabFile(principal1, handler.createSecurePassword(), 0, null);
            Assert.fail("KerberosOperationException not thrown with null file");
        } catch (Throwable t) {
            Assert.assertEquals(KerberosOperationException.class, t.getClass());
        }
    }

    @Test
    public void testCreateKeytabFileFromBase64EncodedData() throws Exception {
        KerberosOperationHandler handler = createHandler();
        File file = folder.newFile();
        final String principal = "principal@REALM.COM";

        Assert.assertTrue(handler.createKeytabFile(principal, handler.createSecurePassword(), 0, file));

        FileInputStream fis = new FileInputStream(file);
        byte[] data = new byte[(int) file.length()];

        Assert.assertEquals(data.length, fis.read(data));
        fis.close();

        File f = handler.createKeytabFile(Base64.encodeBase64String(data));

        try {
            Keytab keytab = Keytab.read(f);
            Assert.assertNotNull(keytab);

            List<KeytabEntry> entries = keytab.getEntries();
            Assert.assertNotNull(entries);
            Assert.assertFalse(entries.isEmpty());

            for (KeytabEntry entry : entries) {
                Assert.assertEquals(principal, entry.getPrincipalName());
            }
        } finally {
            if (!f.delete()) {
                f.deleteOnExit();
            }
        }
    }

    @Test
    public void testMergeKeytabs() throws KerberosOperationException {
        KerberosOperationHandler handler = createHandler();

        Keytab keytab1 = handler.createKeytab("principal@EXAMPLE.COM", "password", 1);
        Keytab keytab2 = handler.createKeytab("principal@EXAMPLE.COM", "password1", 1);
        Keytab keytab3 = handler.createKeytab("principal1@EXAMPLE.COM", "password", 4);

        Keytab merged;

        merged = handler.mergeKeytabs(keytab1, keytab2);
        Assert.assertEquals(keytab1.getEntries().size(), merged.getEntries().size());

        merged = handler.mergeKeytabs(keytab1, keytab3);
        Assert.assertEquals(keytab1.getEntries().size() + keytab3.getEntries().size(), merged.getEntries().size());

        merged = handler.mergeKeytabs(keytab2, keytab3);
        Assert.assertEquals(keytab2.getEntries().size() + keytab3.getEntries().size(), merged.getEntries().size());

        merged = handler.mergeKeytabs(keytab2, merged);
        Assert.assertEquals(keytab2.getEntries().size() + keytab3.getEntries().size(), merged.getEntries().size());
    }

    @Test
    public void testTranslateEncryptionTypes() throws Exception {
        KerberosOperationHandler handler = createHandler();

        Assert.assertEquals(new HashSet<EncryptionType>() {
            {
                add(EncryptionType.AES256_CTS_HMAC_SHA1_96);
                add(EncryptionType.AES128_CTS_HMAC_SHA1_96);
                add(EncryptionType.DES3_CBC_SHA1_KD);
                add(EncryptionType.DES_CBC_MD5);
                add(EncryptionType.DES_CBC_MD4);
                add(EncryptionType.DES_CBC_CRC);
                add(EncryptionType.UNKNOWN);
            }
        }, handler
                .translateEncryptionTypes(
                        "aes256-cts-hmac-sha1-96\n aes128-cts-hmac-sha1-96\tdes3-cbc-sha1 arcfour-hmac-md5 "
                                + "camellia256-cts-cmac camellia128-cts-cmac des-cbc-crc des-cbc-md5 des-cbc-md4",
                        "\\s+"));

        Assert.assertEquals(new HashSet<EncryptionType>() {
            {
                add(EncryptionType.AES256_CTS_HMAC_SHA1_96);
                add(EncryptionType.AES128_CTS_HMAC_SHA1_96);
            }
        }, handler.translateEncryptionTypes("aes", " "));

        Assert.assertEquals(new HashSet<EncryptionType>() {
            {
                add(EncryptionType.AES256_CTS_HMAC_SHA1_96);
            }
        }, handler.translateEncryptionTypes("aes-256", " "));

        Assert.assertEquals(new HashSet<EncryptionType>() {
            {
                add(EncryptionType.DES3_CBC_SHA1_KD);
            }
        }, handler.translateEncryptionTypes("des3", " "));
    }

    @Test
    public void testEscapeCharacters() throws KerberosOperationException {
        KerberosOperationHandler handler = createHandler();

        HashSet<Character> specialCharacters = new HashSet<Character>() {
            {
                add('/');
                add(',');
                add('\\');
                add('#');
                add('+');
                add('<');
                add('>');
                add(';');
                add('"');
                add('=');
                add(' ');
            }
        };

        Assert.assertEquals("\\/\\,\\\\\\#\\+\\<\\>\\;\\\"\\=\\ ",
                handler.escapeCharacters("/,\\#+<>;\"= ", specialCharacters, '\\'));
        Assert.assertNull(handler.escapeCharacters(null, specialCharacters, '\\'));
        Assert.assertEquals("", handler.escapeCharacters("", specialCharacters, '\\'));
        Assert.assertEquals("nothing_special_here",
                handler.escapeCharacters("nothing_special_here", specialCharacters, '\\'));
        Assert.assertEquals("\\/\\,\\\\\\#\\+\\<\\>\\;\\\"\\=\\ ",
                handler.escapeCharacters("/,\\#+<>;\"= ", specialCharacters, '\\'));

        Assert.assertEquals("nothing<>special#here!",
                handler.escapeCharacters("nothing<>special#here!", null, '\\'));
        Assert.assertEquals("nothing<>special#here!",
                handler.escapeCharacters("nothing<>special#here!", Collections.<Character>emptySet(), '\\'));
        Assert.assertEquals("nothing<>special#here!",
                handler.escapeCharacters("nothing<>special#here!", Collections.singleton('?'), '\\'));
        Assert.assertEquals("\\A's are special!",
                handler.escapeCharacters("A's are special!", Collections.singleton('A'), '\\'));
    }

    @Test(expected = KerberosAdminAuthenticationException.class)
    public void testAdminCredentialsNullPrincipal() throws KerberosOperationException {
        KerberosOperationHandler handler = createHandler();

        KerberosCredential credentials = new KerberosCredential(null, "password", null);
        handler.setAdministratorCredentials(credentials);
    }

    @Test(expected = KerberosAdminAuthenticationException.class)
    public void testAdminCredentialsEmptyPrincipal() throws KerberosOperationException {
        KerberosOperationHandler handler = createHandler();

        KerberosCredential credentials = new KerberosCredential("", "password", null);
        handler.setAdministratorCredentials(credentials);
    }

    @Test(expected = KerberosAdminAuthenticationException.class)
    public void testAdminCredentialsNullCredential() throws KerberosOperationException {
        KerberosOperationHandler handler = createHandler();

        KerberosCredential credentials = new KerberosCredential("principal", null, null);
        handler.setAdministratorCredentials(credentials);
    }

    @Test(expected = KerberosAdminAuthenticationException.class)
    public void testAdminCredentialsEmptyCredential1() throws KerberosOperationException {
        KerberosOperationHandler handler = createHandler();

        KerberosCredential credentials = new KerberosCredential("principal", "", null);
        handler.setAdministratorCredentials(credentials);
    }

    @Test(expected = KerberosAdminAuthenticationException.class)
    public void testAdminCredentialsEmptyCredential2() throws KerberosOperationException {
        KerberosOperationHandler handler = createHandler();

        KerberosCredential credentials = new KerberosCredential("principal", null, "");
        handler.setAdministratorCredentials(credentials);
    }

    private KerberosOperationHandler createHandler() throws KerberosOperationException {
        KerberosOperationHandler handler = new KerberosOperationHandler() {

            @Override
            public void open(KerberosCredential administratorCredentials, String defaultRealm,
                    Map<String, String> kerberosConfiguration) throws KerberosOperationException {
                setAdministratorCredentials(administratorCredentials);
                setDefaultRealm(defaultRealm);
            }

            @Override
            public void close() throws KerberosOperationException {

            }

            @Override
            public boolean principalExists(String principal) throws KerberosOperationException {
                return false;
            }

            @Override
            public Integer createPrincipal(String principal, String password, boolean service)
                    throws KerberosOperationException {
                return 0;
            }

            @Override
            public Integer setPrincipalPassword(String principal, String password)
                    throws KerberosOperationException {
                return 0;
            }

            @Override
            public boolean removePrincipal(String principal) throws KerberosOperationException {
                return false;
            }
        };

        handler.open(new KerberosCredential("admin/admin", "hadoop", null), "EXAMPLE.COM", null);
        return handler;
    }
}