You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ze...@apache.org on 2018/01/15 02:38:45 UTC
directory-kerby git commit: DIRKRB-678 Implement MySQL identity
backend for KDC server.
Repository: directory-kerby
Updated Branches:
refs/heads/trunk 7b30a96ee -> 11089e869
DIRKRB-678 Implement MySQL identity backend for KDC server.
Project: http://git-wip-us.apache.org/repos/asf/directory-kerby/repo
Commit: http://git-wip-us.apache.org/repos/asf/directory-kerby/commit/11089e86
Tree: http://git-wip-us.apache.org/repos/asf/directory-kerby/tree/11089e86
Diff: http://git-wip-us.apache.org/repos/asf/directory-kerby/diff/11089e86
Branch: refs/heads/trunk
Commit: 11089e86940723fb2ca5850504b93814b4e794ad
Parents: 7b30a96
Author: zenglinx <fr...@intel.com>
Authored: Mon Jan 15 10:38:30 2018 +0800
Committer: zenglinx <fr...@intel.com>
Committed: Mon Jan 15 10:38:30 2018 +0800
----------------------------------------------------------------------
kerby-backend/mysql-backend/pom.xml | 91 ++++
.../kdc/identitybackend/MySQLConfKey.java | 52 +++
.../identitybackend/MySQLIdentityBackend.java | 437 +++++++++++++++++++
.../identity/backend/MySQLBackendKdcTest.java | 78 ++++
.../kerb/identity/backend/MySQLBackendTest.java | 57 +++
kerby-backend/pom.xml | 1 +
kerby-dist/kdc-dist/conf/backend.conf | 4 +
kerby-dist/kdc-dist/pom.xml | 7 +
8 files changed, 727 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/11089e86/kerby-backend/mysql-backend/pom.xml
----------------------------------------------------------------------
diff --git a/kerby-backend/mysql-backend/pom.xml b/kerby-backend/mysql-backend/pom.xml
new file mode 100644
index 0000000..d24335a
--- /dev/null
+++ b/kerby-backend/mysql-backend/pom.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed 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. See accompanying LICENSE file.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.kerby</groupId>
+ <artifactId>kerby-backend</artifactId>
+ <version>1.1.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>mysql-backend</artifactId>
+ <name>MySQL identity backend</name>
+ <description>MySQL identity backend</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.directory.server</groupId>
+ <artifactId>apacheds-core-api</artifactId>
+ <version>2.0.0-M23</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-dbutils</groupId>
+ <artifactId>commons-dbutils</artifactId>
+ <version>1.6</version>
+ </dependency>
+ <dependency>
+ <groupId>org.drizzle.jdbc</groupId>
+ <artifactId>drizzle-jdbc</artifactId>
+ <version>1.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.kerby</groupId>
+ <artifactId>kerby-config</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.kerby</groupId>
+ <artifactId>kerb-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.kerby</groupId>
+ <artifactId>kerb-identity</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.kerby</groupId>
+ <artifactId>kerb-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ <version>1.4.196</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.kerby</groupId>
+ <artifactId>kerb-identity-test</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.kerby</groupId>
+ <artifactId>kerb-kdc-test</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/11089e86/kerby-backend/mysql-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/MySQLConfKey.java
----------------------------------------------------------------------
diff --git a/kerby-backend/mysql-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/MySQLConfKey.java b/kerby-backend/mysql-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/MySQLConfKey.java
new file mode 100644
index 0000000..ce2ead6
--- /dev/null
+++ b/kerby-backend/mysql-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/MySQLConfKey.java
@@ -0,0 +1,52 @@
+/**
+ * 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.kerby.kerberos.kdc.identitybackend;
+
+import org.apache.kerby.config.ConfigKey;
+
+/**
+ * Define all the MySQL backend related configuration items with default values.
+ */
+public enum MySQLConfKey implements ConfigKey {
+ MYSQL_DRIVER("org.drizzle.jdbc.DrizzleDriver"),
+ MYSQL_URL("jdbc:mysql:thin://127.0.0.1:3306/mysqlbackend"),
+ MYSQL_USER("root"),
+ MYSQL_PASSWORD("passwd");
+
+ private Object defaultValue;
+
+ MySQLConfKey() {
+ this.defaultValue = null;
+ }
+
+ MySQLConfKey(Object defaultValue) {
+ this.defaultValue = defaultValue;
+ }
+
+ @Override
+ public String getPropertyKey() {
+ return name().toLowerCase();
+ }
+
+ @Override
+ public Object getDefaultValue() {
+ return this.defaultValue;
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/11089e86/kerby-backend/mysql-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/MySQLIdentityBackend.java
----------------------------------------------------------------------
diff --git a/kerby-backend/mysql-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/MySQLIdentityBackend.java b/kerby-backend/mysql-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/MySQLIdentityBackend.java
new file mode 100644
index 0000000..32ede90
--- /dev/null
+++ b/kerby-backend/mysql-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/MySQLIdentityBackend.java
@@ -0,0 +1,437 @@
+/**
+ * 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.kerby.kerberos.kdc.identitybackend;
+
+import org.apache.commons.dbutils.DbUtils;
+import org.apache.directory.api.util.GeneralizedTime;
+import org.apache.kerby.config.Config;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.identity.backend.AbstractIdentityBackend;
+import org.apache.kerby.kerberos.kerb.request.KrbIdentity;
+import org.apache.kerby.kerberos.kerb.type.KerberosTime;
+import org.apache.kerby.kerberos.kerb.type.base.EncryptionKey;
+import org.apache.kerby.kerberos.kerb.type.base.EncryptionType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import javax.sql.rowset.serial.SerialBlob;
+
+/**
+ * A MySQL based backend implementation.
+ */
+public class MySQLIdentityBackend extends AbstractIdentityBackend {
+ private Connection connection;
+ private String driver;
+ private String url;
+ private String user;
+ private String password;
+ private static final Logger LOG = LoggerFactory.getLogger(MySQLIdentityBackend.class);
+ private String identityTable;
+ private String keyInfoTable;
+
+ /**
+ * Constructing an instance using specified config that contains anything
+ * to be used to initialize an MySQL Backend.
+ * @param config . The config is used to config the backend.
+ */
+ public MySQLIdentityBackend(final Config config) {
+ setConfig(config);
+ }
+
+ public MySQLIdentityBackend() { }
+
+ /**
+ * Start the MySQL connection.
+ */
+ private void startConnection() throws KrbException {
+ try {
+ Class.forName(driver);
+ connection = DriverManager.getConnection(url, user, password);
+ if (!connection.isClosed()) {
+ LOG.info("Succeeded in connecting to MySQL.");
+ }
+ } catch (ClassNotFoundException e) {
+ throw new KrbException("JDBC Driver Class not found. ", e);
+ } catch (SQLException e) {
+ throw new KrbException("Failed to connecting to MySQL. ", e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void doInitialize() throws KrbException {
+ LOG.info("Initializing the MySQL identity backend.");
+ driver = getConfig().getString(MySQLConfKey.MYSQL_DRIVER, true);
+ user = getConfig().getString(MySQLConfKey.MYSQL_USER, true);
+ password = getConfig().getString(MySQLConfKey.MYSQL_PASSWORD, true);
+
+ String urlString = getConfig().getString(MySQLConfKey.MYSQL_URL, true);
+ if (urlString == null || urlString.isEmpty()) {
+ urlString = getBackendConfig().getString(MySQLConfKey.MYSQL_URL, true);
+ }
+ url = urlString;
+
+ ResultSet resCheckTable = null;
+ PreparedStatement preInitialize = null;
+ PreparedStatement preKdcRealm = null;
+ ResultSet resKdcRealm = null;
+ PreparedStatement preIdentity = null;
+ PreparedStatement preKey = null;
+ try {
+ startConnection();
+
+ resCheckTable = connection.getMetaData().getTables(null, null, "kdc_config", null);
+ if (resCheckTable.next()) {
+ // Set initialized for kdc config table if HAS enabled
+ String stmInitialize = "UPDATE `kdc_config` SET initialized = true WHERE id = 1";
+ preInitialize = connection.prepareStatement(stmInitialize);
+ preInitialize.executeUpdate();
+
+ // Get identity table name according to realm of kdc
+ String stmKdcRealm = "SELECT realm FROM `kdc_config`";
+ preKdcRealm = connection.prepareStatement(stmKdcRealm);
+ resKdcRealm = preKdcRealm.executeQuery();
+ if (resKdcRealm.next()) {
+ String realm = resKdcRealm.getString("realm").toLowerCase();
+ identityTable = "`" + realm + "_identity" + "`";
+ keyInfoTable = "`" + realm + "_key" + "`";
+ } else {
+ throw new KrbException("Failed to get kdc config.");
+ }
+ } else {
+ identityTable = "`" + "kerby_identity" + "`";
+ keyInfoTable = "`" + "kerby_key" + "`";
+ }
+
+ // Create identity table
+ String stmIdentity = "CREATE TABLE IF NOT EXISTS " + identityTable
+ + " (principal varchar(255) NOT NULL, key_version INTEGER "
+ + "DEFAULT 1, kdc_flags INTEGER DEFAULT 0, disabled bool "
+ + "DEFAULT NULL, locked bool DEFAULT NULL, created_time "
+ + "VARCHAR(255) DEFAULT NULL, expire_time VARCHAR(255) "
+ + "DEFAULT NULL, PRIMARY KEY (principal) ) ENGINE=INNODB "
+ + "DEFAULT CHARSET=utf8;";
+ preIdentity = connection.prepareStatement(stmIdentity);
+ preIdentity.executeUpdate();
+
+ // Create key table
+ String stmKey = "CREATE TABLE IF NOT EXISTS " + keyInfoTable
+ + " (key_id INTEGER NOT NULL AUTO_INCREMENT, key_type "
+ + "VARCHAR(255) DEFAULT NULL, kvno INTEGER DEFAULT -1, "
+ + "key_value BLOB DEFAULT NULL, principal VARCHAR(255) NOT NULL,"
+ + "PRIMARY KEY (key_id), INDEX (principal), FOREIGN KEY "
+ + "(principal) REFERENCES " + identityTable + "(principal) "
+ + ") ENGINE=INNODB DEFAULT CHARSET=utf8;";
+ preKey = connection.prepareStatement(stmKey);
+ preKey.executeUpdate();
+
+ } catch (SQLException e) {
+ LOG.error("Error occurred while initialize MySQL backend." + e.toString());
+ throw new KrbException("Failed to create table in database. ", e);
+ } finally {
+ DbUtils.closeQuietly(resCheckTable);
+ DbUtils.closeQuietly(preInitialize);
+ DbUtils.closeQuietly(preKdcRealm);
+ DbUtils.closeQuietly(resKdcRealm);
+ DbUtils.closeQuietly(preIdentity);
+ DbUtils.closeQuietly(preKey);
+ doStop();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void doStop() throws KrbException {
+ try {
+ closeConnection();
+ if (connection.isClosed()) {
+ LOG.info("Succeeded in closing connection with MySQL.");
+ }
+ } catch (SQLException e) {
+ LOG.error("Failed to close connection with MySQL.");
+ throw new KrbException("Failed to close connection with MySQL. ", e);
+ }
+ }
+
+ /**
+ * Close the connection for stop().
+ * @throws SQLException if SQLException handled
+ */
+ private void closeConnection() throws SQLException {
+ if (!connection.isClosed()) {
+ connection.close();
+ }
+ }
+
+ /**
+ * Convert a KerberosTime type object to a generalized time form of String.
+ * @param kerberosTime The kerberos time to convert
+ */
+ private String toGeneralizedTime(final KerberosTime kerberosTime) {
+ GeneralizedTime generalizedTime = new GeneralizedTime(kerberosTime.getValue());
+ return generalizedTime.toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected KrbIdentity doAddIdentity(KrbIdentity identity) throws KrbException {
+ String principalName = identity.getPrincipalName();
+ int keyVersion = identity.getKeyVersion();
+ int kdcFlags = identity.getKdcFlags();
+ boolean disabled = identity.isDisabled();
+ boolean locked = identity.isLocked();
+ String createdTime = toGeneralizedTime(identity.getCreatedTime());
+ String expireTime = toGeneralizedTime(identity.getExpireTime());
+ Map<EncryptionType, EncryptionKey> keys = identity.getKeys();
+
+ PreparedStatement preIdentity = null;
+ PreparedStatement preKey = null;
+
+ KrbIdentity duplicateIdentity = doGetIdentity(principalName);
+ if (duplicateIdentity != null) {
+ LOG.warn("The identity maybe duplicate.");
+
+ return duplicateIdentity;
+ } else {
+ try {
+ startConnection();
+ connection.setAutoCommit(false);
+
+ // Insert identity to identity table
+ String stmIdentity = "insert into " + identityTable
+ + " (principal, key_version, kdc_flags, disabled, locked, created_time, expire_time)"
+ + " values(?, ?, ?, ?, ?, ?, ?)";
+ preIdentity = connection.prepareStatement(stmIdentity);
+ preIdentity.setString(1, principalName);
+ preIdentity.setInt(2, keyVersion);
+ preIdentity.setInt(3, kdcFlags);
+ preIdentity.setBoolean(4, disabled);
+ preIdentity.setBoolean(5, locked);
+ preIdentity.setString(6, createdTime);
+ preIdentity.setString(7, expireTime);
+ preIdentity.executeUpdate();
+
+ // Insert keys to key table
+ for (Map.Entry<EncryptionType, EncryptionKey> entry : keys.entrySet()) {
+ String stmKey = "insert into " + keyInfoTable + " (key_type, kvno, key_value, principal)"
+ + " values(?, ?, ?, ?)";
+ preKey = connection.prepareStatement(stmKey);
+ preKey.setString(1, entry.getKey().getName());
+ preKey.setInt(2, entry.getValue().getKvno());
+ preKey.setBlob(3, new SerialBlob(entry.getValue().getKeyData()));
+ preKey.setString(4, principalName);
+ preKey.executeUpdate();
+ }
+
+ connection.commit();
+ return identity;
+ } catch (SQLException e) {
+ try {
+ LOG.info("Transaction is being rolled back.");
+ connection.rollback();
+ } catch (SQLException ex) {
+ throw new KrbException("Transaction roll back failed. ", ex);
+ }
+ LOG.error("Error occurred while adding identity.");
+ throw new KrbException("Failed to add identity. ", e);
+ } finally {
+ DbUtils.closeQuietly(preIdentity);
+ DbUtils.closeQuietly(preKey);
+ doStop();
+ }
+ }
+ }
+
+ /**
+ * Create kerberos time.
+ * @param generalizedTime generalized time
+ * @throws ParseException parse exception
+ */
+ private KerberosTime createKerberosTime(final String generalizedTime) throws ParseException {
+ long time = new GeneralizedTime(generalizedTime).getTime();
+ return new KerberosTime(time);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected KrbIdentity doGetIdentity(final String principalName) throws KrbException {
+ KrbIdentity krbIdentity = new KrbIdentity(principalName);
+
+ PreparedStatement preIdentity = null;
+ ResultSet resIdentity = null;
+ PreparedStatement preKey = null;
+ ResultSet resKey = null;
+ try {
+ startConnection();
+
+ // Get identity from identity table
+ String stmIdentity = "SELECT * FROM " + identityTable + " where principal = ?";
+ preIdentity = connection.prepareStatement(stmIdentity);
+ preIdentity.setString(1, principalName);
+ resIdentity = preIdentity.executeQuery();
+
+ if (!resIdentity.isBeforeFirst()) {
+ return null;
+ }
+
+ while (resIdentity.next()) {
+ krbIdentity.setKeyVersion(resIdentity.getInt("key_version"));
+ krbIdentity.setKdcFlags(resIdentity.getInt("kdc_flags"));
+ krbIdentity.setDisabled(resIdentity.getBoolean("disabled"));
+ krbIdentity.setLocked(resIdentity.getBoolean("locked"));
+ krbIdentity.setCreatedTime(createKerberosTime(resIdentity.getString("created_time")));
+ krbIdentity.setExpireTime(createKerberosTime(resIdentity.getString("expire_time")));
+ }
+
+ // Get keys from key table
+ List<EncryptionKey> keys = new ArrayList<>();
+ String stmKey = "SELECT * FROM " + keyInfoTable + " where principal = ?";
+ preKey = connection.prepareStatement(stmKey);
+ preKey.setString(1, principalName);
+ resKey = preKey.executeQuery();
+ while (resKey.next()) {
+ int kvno = resKey.getInt("kvno");
+ String keyType = resKey.getString("key_type");
+ EncryptionType eType = EncryptionType.fromName(keyType);
+ byte[] keyValue = resKey.getBytes("key_value");
+ EncryptionKey key = new EncryptionKey(eType, keyValue, kvno);
+ keys.add(key);
+ }
+
+ krbIdentity.addKeys(keys);
+ return krbIdentity;
+ } catch (SQLException e) {
+ LOG.error("Error occurred while getting identity.");
+ throw new KrbException("Failed to get identity. ", e);
+ } catch (ParseException e) {
+ throw new KrbException("Failed to get identity. ", e);
+ } finally {
+ DbUtils.closeQuietly(preIdentity);
+ DbUtils.closeQuietly(resIdentity);
+ DbUtils.closeQuietly(preKey);
+ DbUtils.closeQuietly(resKey);
+ doStop();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected KrbIdentity doUpdateIdentity(KrbIdentity identity) throws KrbException {
+ String principalName = identity.getPrincipalName();
+ try {
+ doDeleteIdentity(principalName); // Delete former identity
+ doAddIdentity(identity); // Insert new identity
+ } catch (KrbException e) {
+ LOG.error("Error occurred while updating identity: " + principalName);
+ throw new KrbException("Failed to update identity. ", e);
+ }
+
+ return getIdentity(principalName);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void doDeleteIdentity(String principalName) throws KrbException {
+ PreparedStatement preKey = null;
+ PreparedStatement preIdentity = null;
+ try {
+ startConnection();
+ connection.setAutoCommit(false);
+
+ // Delete keys from key table
+ String stmKey = "DELETE FROM " + keyInfoTable + " where principal = ?";
+ preKey = connection.prepareStatement(stmKey);
+ preKey.setString(1, principalName);
+ preKey.executeUpdate();
+
+ // Dlete identity from identity table
+ String stmIdentity = "DELETE FROM " + identityTable + " where principal = ? ";
+ preIdentity = connection.prepareStatement(stmIdentity);
+ preIdentity.setString(1, principalName);
+ preIdentity.executeUpdate();
+
+ connection.commit();
+ } catch (SQLException e) {
+ try {
+ LOG.info("Transaction is being rolled back.");
+ connection.rollback();
+ } catch (SQLException ex) {
+ throw new KrbException("Transaction roll back failed. ", ex);
+ }
+ LOG.error("Error occurred while deleting identity.");
+ throw new KrbException("Failed to delete identity. ", e);
+ } finally {
+ DbUtils.closeQuietly(preIdentity);
+ DbUtils.closeQuietly(preKey);
+ doStop();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Iterable<String> doGetIdentities() throws KrbException {
+ List<String> identityNames = new ArrayList<>();
+ PreparedStatement preSmt = null;
+ ResultSet result = null;
+ try {
+ startConnection();
+ String statement = "SELECT * FROM " + identityTable;
+ preSmt = connection.prepareStatement(statement);
+ result = preSmt.executeQuery();
+ while (result.next()) {
+ identityNames.add(result.getString("principal"));
+ }
+ result.close();
+ preSmt.close();
+ } catch (SQLException e) {
+ LOG.error("Error occurred while getting identities.");
+ throw new KrbException("Failed to get identities. ", e);
+ } finally {
+ DbUtils.closeQuietly(preSmt);
+ DbUtils.closeQuietly(result);
+ doStop();
+ }
+
+ return identityNames;
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/11089e86/kerby-backend/mysql-backend/src/test/java/org/apache/kerby/kerberos/kerb/identity/backend/MySQLBackendKdcTest.java
----------------------------------------------------------------------
diff --git a/kerby-backend/mysql-backend/src/test/java/org/apache/kerby/kerberos/kerb/identity/backend/MySQLBackendKdcTest.java b/kerby-backend/mysql-backend/src/test/java/org/apache/kerby/kerberos/kerb/identity/backend/MySQLBackendKdcTest.java
new file mode 100644
index 0000000..565a0ee
--- /dev/null
+++ b/kerby-backend/mysql-backend/src/test/java/org/apache/kerby/kerberos/kerb/identity/backend/MySQLBackendKdcTest.java
@@ -0,0 +1,78 @@
+/**
+ * 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.kerby.kerberos.kerb.identity.backend;
+
+import org.apache.kerby.kerberos.kdc.identitybackend.MySQLConfKey;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.server.KdcConfigKey;
+import org.apache.kerby.kerberos.kerb.server.KdcTestBase;
+import org.apache.kerby.kerberos.kerb.type.ticket.SgtTicket;
+import org.apache.kerby.kerberos.kerb.type.ticket.TgtTicket;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class MySQLBackendKdcTest extends KdcTestBase {
+ private static File testDir = new File(System.getProperty("test.dir", "target"));
+ private static File dbFile = new File(testDir, "mysqlbackend.mv.db");
+
+ @After
+ public void tearDown() {
+ if (dbFile.exists() && !dbFile.delete()) {
+ System.err.println("Failed to delete the test database file.");
+ }
+ }
+
+ @Override
+ protected void prepareKdc() throws KrbException {
+ BackendConfig backendConfig = getKdcServer().getBackendConfig();
+
+ backendConfig.setString(KdcConfigKey.KDC_IDENTITY_BACKEND,
+ "org.apache.kerby.kerberos.kdc.identitybackend.MySQLIdentityBackend");
+ backendConfig.setString(MySQLConfKey.MYSQL_DRIVER, "org.h2.Driver");
+ backendConfig.setString(MySQLConfKey.MYSQL_URL,
+ "jdbc:h2:" + testDir.getAbsolutePath() + "/mysqlbackend;MODE=MySQL");
+ backendConfig.setString(MySQLConfKey.MYSQL_USER, "root");
+ backendConfig.setString(MySQLConfKey.MYSQL_PASSWORD, "123456");
+
+ super.prepareKdc();
+ }
+
+ @Test
+ public void testKdc() {
+ TgtTicket tgt;
+ SgtTicket tkt;
+
+ try {
+ tgt = getKrbClient().requestTgt(getClientPrincipal(), getClientPassword());
+ assertThat(tgt).isNotNull();
+
+ tkt = getKrbClient().requestSgt(tgt, getServerPrincipal());
+ assertThat(tkt).isNotNull();
+ } catch (Exception e) {
+ Assert.fail("Exception occurred with good password. "
+ + e.toString());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/11089e86/kerby-backend/mysql-backend/src/test/java/org/apache/kerby/kerberos/kerb/identity/backend/MySQLBackendTest.java
----------------------------------------------------------------------
diff --git a/kerby-backend/mysql-backend/src/test/java/org/apache/kerby/kerberos/kerb/identity/backend/MySQLBackendTest.java b/kerby-backend/mysql-backend/src/test/java/org/apache/kerby/kerberos/kerb/identity/backend/MySQLBackendTest.java
new file mode 100644
index 0000000..59f3500
--- /dev/null
+++ b/kerby-backend/mysql-backend/src/test/java/org/apache/kerby/kerberos/kerb/identity/backend/MySQLBackendTest.java
@@ -0,0 +1,57 @@
+/**
+ * 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.kerby.kerberos.kerb.identity.backend;
+
+import org.apache.kerby.config.Conf;
+import org.apache.kerby.kerberos.kdc.identitybackend.MySQLConfKey;
+import org.apache.kerby.kerberos.kdc.identitybackend.MySQLIdentityBackend;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+import java.io.File;
+import java.io.IOException;
+
+public class MySQLBackendTest extends BackendTestBase {
+ private static File testDir = new File(System.getProperty("test.dir", "target"));
+ private static File dbFile = new File(testDir, "mysqlbackend.mv.db");
+
+ @BeforeClass
+ public static void setup() throws KrbException, IOException {
+ Conf config = new Conf();
+ config.setString(MySQLConfKey.MYSQL_DRIVER, "org.h2.Driver");
+ config.setString(MySQLConfKey.MYSQL_URL,
+ "jdbc:h2:" + testDir.getCanonicalPath() + "/mysqlbackend;MODE=MySQL");
+ config.setString(MySQLConfKey.MYSQL_USER, "root");
+ config.setString(MySQLConfKey.MYSQL_PASSWORD, "123456");
+ backend = new MySQLIdentityBackend(config);
+ backend.initialize();
+ }
+
+ @AfterClass
+ public static void tearDown() throws KrbException {
+ if (backend != null) {
+ backend.stop();
+ }
+ if (dbFile.exists() && !dbFile.delete()) {
+ System.err.println("Failed to delete the test database file.");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/11089e86/kerby-backend/pom.xml
----------------------------------------------------------------------
diff --git a/kerby-backend/pom.xml b/kerby-backend/pom.xml
index ef95b87..6ce432c 100644
--- a/kerby-backend/pom.xml
+++ b/kerby-backend/pom.xml
@@ -53,6 +53,7 @@
<module>ldap-backend</module>
<module>mavibot-backend</module>
<module>zookeeper-backend</module>
+ <module>mysql-backend</module>
</modules>
</profile>
</profiles>
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/11089e86/kerby-dist/kdc-dist/conf/backend.conf
----------------------------------------------------------------------
diff --git a/kerby-dist/kdc-dist/conf/backend.conf b/kerby-dist/kdc-dist/conf/backend.conf
index 2ead268..20134ef 100644
--- a/kerby-dist/kdc-dist/conf/backend.conf
+++ b/kerby-dist/kdc-dist/conf/backend.conf
@@ -22,3 +22,7 @@ embedded_zk = false
zk_host = 127.0.0.1
zk_port = 2181
data_dir = /tmp/zookeeper/data
+mysql_driver = org.drizzle.jdbc.DrizzleDriver
+mysql_url = jdbc:mysql:thin://127.0.0.1:3306/mysqlbackend?createDB=true
+mysql_user = root
+mysql_password = passwd
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/11089e86/kerby-dist/kdc-dist/pom.xml
----------------------------------------------------------------------
diff --git a/kerby-dist/kdc-dist/pom.xml b/kerby-dist/kdc-dist/pom.xml
index 1766d28..3a5de2d 100644
--- a/kerby-dist/kdc-dist/pom.xml
+++ b/kerby-dist/kdc-dist/pom.xml
@@ -89,6 +89,13 @@
<version>${gson.version}</version>
</dependency>
+ <!-- For mysql backend -->
+ <dependency>
+ <groupId>org.apache.kerby</groupId>
+ <artifactId>mysql-backend</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
<!-- For common and misc -->
<dependency>
<groupId>org.slf4j</groupId>
RE: directory-kerby git commit: DIRKRB-678 Implement MySQL identity
backend for KDC server.
Posted by "Zeng, Frank" <fr...@intel.com>.
Hi Colm,
Thanks for your suggestion.
a) I will fix it soon.
b) I will use the KerberosTime.getTime() method to save the Kerberos time column of identity.
c) yes, thanks for your remind.
P.S. I created a new issue named DIRKRB-686 for these refactor work.
Thanks,
Frank
-----Original Message-----
From: Colm O hEigeartaigh [mailto:coheigea@apache.org]
Sent: Monday, January 15, 2018 5:49 PM
To: kerby@directory.apache.org
Subject: Re: directory-kerby git commit: DIRKRB-678 Implement MySQL identity backend for KDC server.
Hi Frank,
I'd like to suggest a few small changes to this commit:
a) The mysql-backend uses different versions for junit + Apache Directory as defined in the parent pom. So instead of 2.0.0-M23 for Apache Directory you can use ${apacheds.version}. You can remove the junit version + test scope because it's defined in the root pom under dependencyManagement.
b) The Apache Directory API is only used to call on GeneralizedTime, but this pulls in a large number of dependencies in the distribution. Can we replace GeneralizedTime with something else, or just pull GeneralizedTime into our project directly?
c) I think the mysql-backend dependency should be commented out in the kerby-dist pom.
Colm.
On Mon, Jan 15, 2018 at 2:38 AM, <ze...@apache.org> wrote:
> Repository: directory-kerby
> Updated Branches:
> refs/heads/trunk 7b30a96ee -> 11089e869
>
>
> DIRKRB-678 Implement MySQL identity backend for KDC server.
>
>
> Project: http://git-wip-us.apache.org/repos/asf/directory-kerby/repo
> Commit: http://git-wip-us.apache.org/repos/asf/directory-kerby/
> commit/11089e86
> Tree:
> http://git-wip-us.apache.org/repos/asf/directory-kerby/tree/11089e86
> Diff:
> http://git-wip-us.apache.org/repos/asf/directory-kerby/diff/11089e86
>
> Branch: refs/heads/trunk
> Commit: 11089e86940723fb2ca5850504b93814b4e794ad
> Parents: 7b30a96
> Author: zenglinx <fr...@intel.com>
> Authored: Mon Jan 15 10:38:30 2018 +0800
> Committer: zenglinx <fr...@intel.com>
> Committed: Mon Jan 15 10:38:30 2018 +0800
>
> ----------------------------------------------------------------------
> kerby-backend/mysql-backend/pom.xml | 91 ++++
> .../kdc/identitybackend/MySQLConfKey.java | 52 +++
> .../identitybackend/MySQLIdentityBackend.java | 437 +++++++++++++++++++
> .../identity/backend/MySQLBackendKdcTest.java | 78 ++++
> .../kerb/identity/backend/MySQLBackendTest.java | 57 +++
> kerby-backend/pom.xml | 1 +
> kerby-dist/kdc-dist/conf/backend.conf | 4 +
> kerby-dist/kdc-dist/pom.xml | 7 +
> 8 files changed, 727 insertions(+)
> ----------------------------------------------------------------------
>
>
> http://git-wip-us.apache.org/repos/asf/directory-kerby/
> blob/11089e86/kerby-backend/mysql-backend/pom.xml
> ----------------------------------------------------------------------
> diff --git a/kerby-backend/mysql-backend/pom.xml
> b/kerby-backend/mysql-backend/pom.xml
> new file mode 100644
> index 0000000..d24335a
> --- /dev/null
> +++ b/kerby-backend/mysql-backend/pom.xml
> @@ -0,0 +1,91 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +<!--
> + Licensed 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. See accompanying LICENSE file.
> +-->
> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="
> http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://
> maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
> + <modelVersion>4.0.0</modelVersion>
> +
> + <parent>
> + <groupId>org.apache.kerby</groupId>
> + <artifactId>kerby-backend</artifactId>
> + <version>1.1.1-SNAPSHOT</version> </parent>
> +
> + <artifactId>mysql-backend</artifactId>
> + <name>MySQL identity backend</name> <description>MySQL identity
> + backend</description>
> +
> + <dependencies>
> + <dependency>
> + <groupId>org.apache.directory.server</groupId>
> + <artifactId>apacheds-core-api</artifactId>
> + <version>2.0.0-M23</version>
> + </dependency>
> + <dependency>
> + <groupId>commons-dbutils</groupId>
> + <artifactId>commons-dbutils</artifactId>
> + <version>1.6</version>
> + </dependency>
> + <dependency>
> + <groupId>org.drizzle.jdbc</groupId>
> + <artifactId>drizzle-jdbc</artifactId>
> + <version>1.4</version>
> + </dependency>
> + <dependency>
> + <groupId>org.apache.kerby</groupId>
> + <artifactId>kerby-config</artifactId>
> + <version>${project.version}</version>
> + </dependency>
> + <dependency>
> + <groupId>org.apache.kerby</groupId>
> + <artifactId>kerb-core</artifactId>
> + <version>${project.version}</version>
> + </dependency>
> + <dependency>
> + <groupId>org.apache.kerby</groupId>
> + <artifactId>kerb-identity</artifactId>
> + <version>${project.version}</version>
> + </dependency>
> + <dependency>
> + <groupId>org.apache.kerby</groupId>
> + <artifactId>kerb-common</artifactId>
> + <version>${project.version}</version>
> + </dependency>
> + <dependency>
> + <groupId>junit</groupId>
> + <artifactId>junit</artifactId>
> + <version>4.11</version>
> + <scope>test</scope>
> + </dependency>
> + <dependency>
> + <groupId>com.h2database</groupId>
> + <artifactId>h2</artifactId>
> + <version>1.4.196</version>
> + <scope>test</scope>
> + </dependency>
> + <dependency>
> + <groupId>org.apache.kerby</groupId>
> + <artifactId>kerb-identity-test</artifactId>
> + <version>${project.version}</version>
> + <scope>test</scope>
> + </dependency>
> + <dependency>
> + <groupId>org.apache.kerby</groupId>
> + <artifactId>kerb-kdc-test</artifactId>
> + <version>${project.version}</version>
> + <type>test-jar</type>
> + <scope>test</scope>
> + </dependency>
> + </dependencies>
> +
> +</project>
> \ No newline at end of file
>
> http://git-wip-us.apache.org/repos/asf/directory-kerby/
> blob/11089e86/kerby-backend/mysql-backend/src/main/java/
> org/apache/kerby/kerberos/kdc/identitybackend/MySQLConfKey.java
> ----------------------------------------------------------------------
> diff --git a/kerby-backend/mysql-backend/src/main/java/org/apache/
> kerby/kerberos/kdc/identitybackend/MySQLConfKey.java
> b/kerby-backend/mysql-backend/src/main/java/org/apache/kerby/kerberos/
> kdc/
> identitybackend/MySQLConfKey.java
> new file mode 100644
> index 0000000..ce2ead6
> --- /dev/null
> +++ b/kerby-backend/mysql-backend/src/main/java/org/apache/
> kerby/kerberos/kdc/identitybackend/MySQLConfKey.java
> @@ -0,0 +1,52 @@
> +/**
> + * 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.kerby.kerberos.kdc.identitybackend;
> +
> +import org.apache.kerby.config.ConfigKey;
> +
> +/**
> + * Define all the MySQL backend related configuration items with
> +default
> values.
> + */
> +public enum MySQLConfKey implements ConfigKey {
> + MYSQL_DRIVER("org.drizzle.jdbc.DrizzleDriver"),
> + MYSQL_URL("jdbc:mysql:thin://127.0.0.1:3306/mysqlbackend"),
> + MYSQL_USER("root"),
> + MYSQL_PASSWORD("passwd");
> +
> + private Object defaultValue;
> +
> + MySQLConfKey() {
> + this.defaultValue = null;
> + }
> +
> + MySQLConfKey(Object defaultValue) {
> + this.defaultValue = defaultValue;
> + }
> +
> + @Override
> + public String getPropertyKey() {
> + return name().toLowerCase();
> + }
> +
> + @Override
> + public Object getDefaultValue() {
> + return this.defaultValue;
> + }
> +}
>
> http://git-wip-us.apache.org/repos/asf/directory-kerby/
> blob/11089e86/kerby-backend/mysql-backend/src/main/java/
> org/apache/kerby/kerberos/kdc/identitybackend/MySQLIdentityBackend.jav
> a
> ----------------------------------------------------------------------
> diff --git a/kerby-backend/mysql-backend/src/main/java/org/apache/
> kerby/kerberos/kdc/identitybackend/MySQLIdentityBackend.java
> b/kerby-backend/mysql-backend/src/main/java/org/apache/kerby/kerberos/
> kdc/ identitybackend/MySQLIdentityBackend.java
> new file mode 100644
> index 0000000..32ede90
> --- /dev/null
> +++ b/kerby-backend/mysql-backend/src/main/java/org/apache/
> kerby/kerberos/kdc/identitybackend/MySQLIdentityBackend.java
> @@ -0,0 +1,437 @@
> +/**
> + * 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.kerby.kerberos.kdc.identitybackend;
> +
> +import org.apache.commons.dbutils.DbUtils;
> +import org.apache.directory.api.util.GeneralizedTime;
> +import org.apache.kerby.config.Config; import
> +org.apache.kerby.kerberos.kerb.KrbException;
> +import org.apache.kerby.kerberos.kerb.identity.backend.
> AbstractIdentityBackend;
> +import org.apache.kerby.kerberos.kerb.request.KrbIdentity;
> +import org.apache.kerby.kerberos.kerb.type.KerberosTime;
> +import org.apache.kerby.kerberos.kerb.type.base.EncryptionKey;
> +import org.apache.kerby.kerberos.kerb.type.base.EncryptionType;
> +import org.slf4j.Logger;
> +import org.slf4j.LoggerFactory;
> +
> +import java.sql.Connection;
> +import java.sql.DriverManager;
> +import java.sql.PreparedStatement;
> +import java.sql.ResultSet;
> +import java.sql.SQLException;
> +import java.text.ParseException;
> +import java.util.ArrayList;
> +import java.util.List;
> +import java.util.Map;
> +import javax.sql.rowset.serial.SerialBlob;
> +
> +/**
> + * A MySQL based backend implementation.
> + */
> +public class MySQLIdentityBackend extends AbstractIdentityBackend {
> + private Connection connection;
> + private String driver;
> + private String url;
> + private String user;
> + private String password;
> + private static final Logger LOG = LoggerFactory.getLogger(
> MySQLIdentityBackend.class);
> + private String identityTable;
> + private String keyInfoTable;
> +
> + /**
> + * Constructing an instance using specified config that contains
> anything
> + * to be used to initialize an MySQL Backend.
> + * @param config . The config is used to config the backend.
> + */
> + public MySQLIdentityBackend(final Config config) {
> + setConfig(config);
> + }
> +
> + public MySQLIdentityBackend() { }
> +
> + /**
> + * Start the MySQL connection.
> + */
> + private void startConnection() throws KrbException {
> + try {
> + Class.forName(driver);
> + connection = DriverManager.getConnection(url, user,
> password);
> + if (!connection.isClosed()) {
> + LOG.info("Succeeded in connecting to MySQL.");
> + }
> + } catch (ClassNotFoundException e) {
> + throw new KrbException("JDBC Driver Class not found. ", e);
> + } catch (SQLException e) {
> + throw new KrbException("Failed to connecting to MySQL. ", e);
> + }
> + }
> +
> + /**
> + * {@inheritDoc}
> + */
> + @Override
> + protected void doInitialize() throws KrbException {
> + LOG.info("Initializing the MySQL identity backend.");
> + driver = getConfig().getString(MySQLConfKey.MYSQL_DRIVER, true);
> + user = getConfig().getString(MySQLConfKey.MYSQL_USER, true);
> + password = getConfig().getString(MySQLConfKey.MYSQL_PASSWORD,
> true);
> +
> + String urlString =
> + getConfig().getString(MySQLConfKey.MYSQL_URL,
> true);
> + if (urlString == null || urlString.isEmpty()) {
> + urlString =
> + getBackendConfig().getString(MySQLConfKey.MYSQL_URL,
> true);
> + }
> + url = urlString;
> +
> + ResultSet resCheckTable = null;
> + PreparedStatement preInitialize = null;
> + PreparedStatement preKdcRealm = null;
> + ResultSet resKdcRealm = null;
> + PreparedStatement preIdentity = null;
> + PreparedStatement preKey = null;
> + try {
> + startConnection();
> +
> + resCheckTable = connection.getMetaData().getTables(null,
> null, "kdc_config", null);
> + if (resCheckTable.next()) {
> + // Set initialized for kdc config table if HAS enabled
> + String stmInitialize = "UPDATE `kdc_config` SET
> initialized = true WHERE id = 1";
> + preInitialize = connection.prepareStatement(
> stmInitialize);
> + preInitialize.executeUpdate();
> +
> + // Get identity table name according to realm of kdc
> + String stmKdcRealm = "SELECT realm FROM `kdc_config`";
> + preKdcRealm = connection.prepareStatement(stmKdcRealm);
> + resKdcRealm = preKdcRealm.executeQuery();
> + if (resKdcRealm.next()) {
> + String realm = resKdcRealm.getString("realm")
> .toLowerCase();
> + identityTable = "`" + realm + "_identity" + "`";
> + keyInfoTable = "`" + realm + "_key" + "`";
> + } else {
> + throw new KrbException("Failed to get kdc config.");
> + }
> + } else {
> + identityTable = "`" + "kerby_identity" + "`";
> + keyInfoTable = "`" + "kerby_key" + "`";
> + }
> +
> + // Create identity table
> + String stmIdentity = "CREATE TABLE IF NOT EXISTS " +
> identityTable
> + + " (principal varchar(255) NOT NULL, key_version
> + INTEGER
> "
> + + "DEFAULT 1, kdc_flags INTEGER DEFAULT 0, disabled bool "
> + + "DEFAULT NULL, locked bool DEFAULT NULL, created_time "
> + + "VARCHAR(255) DEFAULT NULL, expire_time VARCHAR(255) "
> + + "DEFAULT NULL, PRIMARY KEY (principal) ) ENGINE=INNODB "
> + + "DEFAULT CHARSET=utf8;";
> + preIdentity = connection.prepareStatement(stmIdentity);
> + preIdentity.executeUpdate();
> +
> + // Create key table
> + String stmKey = "CREATE TABLE IF NOT EXISTS " + keyInfoTable
> + + " (key_id INTEGER NOT NULL AUTO_INCREMENT, key_type "
> + + "VARCHAR(255) DEFAULT NULL, kvno INTEGER DEFAULT -1, "
> + + "key_value BLOB DEFAULT NULL, principal
> + VARCHAR(255)
> NOT NULL,"
> + + "PRIMARY KEY (key_id), INDEX (principal), FOREIGN KEY "
> + + "(principal) REFERENCES " + identityTable +
> "(principal) "
> + + ") ENGINE=INNODB DEFAULT CHARSET=utf8;";
> + preKey = connection.prepareStatement(stmKey);
> + preKey.executeUpdate();
> +
> + } catch (SQLException e) {
> + LOG.error("Error occurred while initialize MySQL
> + backend." +
> e.toString());
> + throw new KrbException("Failed to create table in database.
> ", e);
> + } finally {
> + DbUtils.closeQuietly(resCheckTable);
> + DbUtils.closeQuietly(preInitialize);
> + DbUtils.closeQuietly(preKdcRealm);
> + DbUtils.closeQuietly(resKdcRealm);
> + DbUtils.closeQuietly(preIdentity);
> + DbUtils.closeQuietly(preKey);
> + doStop();
> + }
> + }
> +
> + /**
> + * {@inheritDoc}
> + */
> + @Override
> + protected void doStop() throws KrbException {
> + try {
> + closeConnection();
> + if (connection.isClosed()) {
> + LOG.info("Succeeded in closing connection with MySQL.");
> + }
> + } catch (SQLException e) {
> + LOG.error("Failed to close connection with MySQL.");
> + throw new KrbException("Failed to close connection with
> MySQL. ", e);
> + }
> + }
> +
> + /**
> + * Close the connection for stop().
> + * @throws SQLException if SQLException handled
> + */
> + private void closeConnection() throws SQLException {
> + if (!connection.isClosed()) {
> + connection.close();
> + }
> + }
> +
> + /**
> + * Convert a KerberosTime type object to a generalized time form
> + of
> String.
> + * @param kerberosTime The kerberos time to convert
> + */
> + private String toGeneralizedTime(final KerberosTime kerberosTime) {
> + GeneralizedTime generalizedTime = new
> GeneralizedTime(kerberosTime.getValue());
> + return generalizedTime.toString();
> + }
> +
> + /**
> + * {@inheritDoc}
> + */
> + @Override
> + protected KrbIdentity doAddIdentity(KrbIdentity identity) throws
> KrbException {
> + String principalName = identity.getPrincipalName();
> + int keyVersion = identity.getKeyVersion();
> + int kdcFlags = identity.getKdcFlags();
> + boolean disabled = identity.isDisabled();
> + boolean locked = identity.isLocked();
> + String createdTime = toGeneralizedTime(identity.
> getCreatedTime());
> + String expireTime = toGeneralizedTime(identity.getExpireTime());
> + Map<EncryptionType, EncryptionKey> keys = identity.getKeys();
> +
> + PreparedStatement preIdentity = null;
> + PreparedStatement preKey = null;
> +
> + KrbIdentity duplicateIdentity = doGetIdentity(principalName);
> + if (duplicateIdentity != null) {
> + LOG.warn("The identity maybe duplicate.");
> +
> + return duplicateIdentity;
> + } else {
> + try {
> + startConnection();
> + connection.setAutoCommit(false);
> +
> + // Insert identity to identity table
> + String stmIdentity = "insert into " + identityTable
> + + " (principal, key_version, kdc_flags,
> + disabled,
> locked, created_time, expire_time)"
> + + " values(?, ?, ?, ?, ?, ?, ?)";
> + preIdentity = connection.prepareStatement(stmIdentity);
> + preIdentity.setString(1, principalName);
> + preIdentity.setInt(2, keyVersion);
> + preIdentity.setInt(3, kdcFlags);
> + preIdentity.setBoolean(4, disabled);
> + preIdentity.setBoolean(5, locked);
> + preIdentity.setString(6, createdTime);
> + preIdentity.setString(7, expireTime);
> + preIdentity.executeUpdate();
> +
> + // Insert keys to key table
> + for (Map.Entry<EncryptionType, EncryptionKey> entry :
> keys.entrySet()) {
> + String stmKey = "insert into " + keyInfoTable + "
> (key_type, kvno, key_value, principal)"
> + + " values(?, ?, ?, ?)";
> + preKey = connection.prepareStatement(stmKey);
> + preKey.setString(1, entry.getKey().getName());
> + preKey.setInt(2, entry.getValue().getKvno());
> + preKey.setBlob(3, new SerialBlob(entry.getValue().
> getKeyData()));
> + preKey.setString(4, principalName);
> + preKey.executeUpdate();
> + }
> +
> + connection.commit();
> + return identity;
> + } catch (SQLException e) {
> + try {
> + LOG.info("Transaction is being rolled back.");
> + connection.rollback();
> + } catch (SQLException ex) {
> + throw new KrbException("Transaction roll back failed.
> ", ex);
> + }
> + LOG.error("Error occurred while adding identity.");
> + throw new KrbException("Failed to add identity. ", e);
> + } finally {
> + DbUtils.closeQuietly(preIdentity);
> + DbUtils.closeQuietly(preKey);
> + doStop();
> + }
> + }
> + }
> +
> + /**
> + * Create kerberos time.
> + * @param generalizedTime generalized time
> + * @throws ParseException parse exception
> + */
> + private KerberosTime createKerberosTime(final String
> + generalizedTime)
> throws ParseException {
> + long time = new GeneralizedTime(generalizedTime).getTime();
> + return new KerberosTime(time);
> + }
> +
> + /**
> + * {@inheritDoc}
> + */
> + @Override
> + protected KrbIdentity doGetIdentity(final String principalName)
> throws KrbException {
> + KrbIdentity krbIdentity = new KrbIdentity(principalName);
> +
> + PreparedStatement preIdentity = null;
> + ResultSet resIdentity = null;
> + PreparedStatement preKey = null;
> + ResultSet resKey = null;
> + try {
> + startConnection();
> +
> + // Get identity from identity table
> + String stmIdentity = "SELECT * FROM " + identityTable + "
> where principal = ?";
> + preIdentity = connection.prepareStatement(stmIdentity);
> + preIdentity.setString(1, principalName);
> + resIdentity = preIdentity.executeQuery();
> +
> + if (!resIdentity.isBeforeFirst()) {
> + return null;
> + }
> +
> + while (resIdentity.next()) {
> + krbIdentity.setKeyVersion(resIdentity.getInt("key_
> version"));
> + krbIdentity.setKdcFlags(resIdentity.getInt("kdc_flags"));
> + krbIdentity.setDisabled(resIdentity.getBoolean("
> disabled"));
> + krbIdentity.setLocked(resIdentity.getBoolean("locked"));
> + krbIdentity.setCreatedTime(createKerberosTime(
> resIdentity.getString("created_time")));
> + krbIdentity.setExpireTime(createKerberosTime(
> resIdentity.getString("expire_time")));
> + }
> +
> + // Get keys from key table
> + List<EncryptionKey> keys = new ArrayList<>();
> + String stmKey = "SELECT * FROM " + keyInfoTable + " where
> principal = ?";
> + preKey = connection.prepareStatement(stmKey);
> + preKey.setString(1, principalName);
> + resKey = preKey.executeQuery();
> + while (resKey.next()) {
> + int kvno = resKey.getInt("kvno");
> + String keyType = resKey.getString("key_type");
> + EncryptionType eType = EncryptionType.fromName(keyType);
> + byte[] keyValue = resKey.getBytes("key_value");
> + EncryptionKey key = new EncryptionKey(eType,
> + keyValue,
> kvno);
> + keys.add(key);
> + }
> +
> + krbIdentity.addKeys(keys);
> + return krbIdentity;
> + } catch (SQLException e) {
> + LOG.error("Error occurred while getting identity.");
> + throw new KrbException("Failed to get identity. ", e);
> + } catch (ParseException e) {
> + throw new KrbException("Failed to get identity. ", e);
> + } finally {
> + DbUtils.closeQuietly(preIdentity);
> + DbUtils.closeQuietly(resIdentity);
> + DbUtils.closeQuietly(preKey);
> + DbUtils.closeQuietly(resKey);
> + doStop();
> + }
> + }
> +
> + /**
> + * {@inheritDoc}
> + */
> + @Override
> + protected KrbIdentity doUpdateIdentity(KrbIdentity identity)
> + throws
> KrbException {
> + String principalName = identity.getPrincipalName();
> + try {
> + doDeleteIdentity(principalName); // Delete former identity
> + doAddIdentity(identity); // Insert new identity
> + } catch (KrbException e) {
> + LOG.error("Error occurred while updating identity: " +
> principalName);
> + throw new KrbException("Failed to update identity. ", e);
> + }
> +
> + return getIdentity(principalName);
> + }
> +
> + /**
> + * {@inheritDoc}
> + */
> + @Override
> + protected void doDeleteIdentity(String principalName) throws
> KrbException {
> + PreparedStatement preKey = null;
> + PreparedStatement preIdentity = null;
> + try {
> + startConnection();
> + connection.setAutoCommit(false);
> +
> + // Delete keys from key table
> + String stmKey = "DELETE FROM " + keyInfoTable + " where
> principal = ?";
> + preKey = connection.prepareStatement(stmKey);
> + preKey.setString(1, principalName);
> + preKey.executeUpdate();
> +
> + // Dlete identity from identity table
> + String stmIdentity = "DELETE FROM " + identityTable + "
> + where
> principal = ? ";
> + preIdentity = connection.prepareStatement(stmIdentity);
> + preIdentity.setString(1, principalName);
> + preIdentity.executeUpdate();
> +
> + connection.commit();
> + } catch (SQLException e) {
> + try {
> + LOG.info("Transaction is being rolled back.");
> + connection.rollback();
> + } catch (SQLException ex) {
> + throw new KrbException("Transaction roll back failed.
> + ",
> ex);
> + }
> + LOG.error("Error occurred while deleting identity.");
> + throw new KrbException("Failed to delete identity. ", e);
> + } finally {
> + DbUtils.closeQuietly(preIdentity);
> + DbUtils.closeQuietly(preKey);
> + doStop();
> + }
> + }
> +
> + /**
> + * {@inheritDoc}
> + */
> + @Override
> + protected Iterable<String> doGetIdentities() throws KrbException {
> + List<String> identityNames = new ArrayList<>();
> + PreparedStatement preSmt = null;
> + ResultSet result = null;
> + try {
> + startConnection();
> + String statement = "SELECT * FROM " + identityTable;
> + preSmt = connection.prepareStatement(statement);
> + result = preSmt.executeQuery();
> + while (result.next()) {
> + identityNames.add(result.getString("principal"));
> + }
> + result.close();
> + preSmt.close();
> + } catch (SQLException e) {
> + LOG.error("Error occurred while getting identities.");
> + throw new KrbException("Failed to get identities. ", e);
> + } finally {
> + DbUtils.closeQuietly(preSmt);
> + DbUtils.closeQuietly(result);
> + doStop();
> + }
> +
> + return identityNames;
> + }
> +}
>
> http://git-wip-us.apache.org/repos/asf/directory-kerby/
> blob/11089e86/kerby-backend/mysql-backend/src/test/java/
> org/apache/kerby/kerberos/kerb/identity/backend/MySQLBackendKdcTest.ja
> va
> ----------------------------------------------------------------------
> diff --git a/kerby-backend/mysql-backend/src/test/java/org/apache/
> kerby/kerberos/kerb/identity/backend/MySQLBackendKdcTest.java
> b/kerby-backend/mysql-backend/src/test/java/org/apache/
> kerby/kerberos/kerb/identity/backend/MySQLBackendKdcTest.java
> new file mode 100644
> index 0000000..565a0ee
> --- /dev/null
> +++ b/kerby-backend/mysql-backend/src/test/java/org/apache/
> kerby/kerberos/kerb/identity/backend/MySQLBackendKdcTest.java
> @@ -0,0 +1,78 @@
> +/**
> + * 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.kerby.kerberos.kerb.identity.backend;
> +
> +import org.apache.kerby.kerberos.kdc.identitybackend.MySQLConfKey;
> +import org.apache.kerby.kerberos.kerb.KrbException;
> +import org.apache.kerby.kerberos.kerb.server.KdcConfigKey;
> +import org.apache.kerby.kerberos.kerb.server.KdcTestBase;
> +import org.apache.kerby.kerberos.kerb.type.ticket.SgtTicket;
> +import org.apache.kerby.kerberos.kerb.type.ticket.TgtTicket;
> +import org.junit.After;
> +import org.junit.Assert;
> +import org.junit.Test;
> +
> +import java.io.File;
> +
> +import static org.assertj.core.api.Assertions.assertThat;
> +
> +public class MySQLBackendKdcTest extends KdcTestBase {
> + private static File testDir = new
> +File(System.getProperty("test.dir",
> "target"));
> + private static File dbFile = new File(testDir,
> + "mysqlbackend.mv.db");
> +
> + @After
> + public void tearDown() {
> + if (dbFile.exists() && !dbFile.delete()) {
> + System.err.println("Failed to delete the test database
> file.");
> + }
> + }
> +
> + @Override
> + protected void prepareKdc() throws KrbException {
> + BackendConfig backendConfig =
> + getKdcServer().getBackendConfig();
> +
> + backendConfig.setString(KdcConfigKey.KDC_IDENTITY_BACKEND,
> + "org.apache.kerby.kerberos.kdc.identitybackend.
> MySQLIdentityBackend");
> + backendConfig.setString(MySQLConfKey.MYSQL_DRIVER,
> "org.h2.Driver");
> + backendConfig.setString(MySQLConfKey.MYSQL_URL,
> + "jdbc:h2:" + testDir.getAbsolutePath() +
> "/mysqlbackend;MODE=MySQL");
> + backendConfig.setString(MySQLConfKey.MYSQL_USER, "root");
> + backendConfig.setString(MySQLConfKey.MYSQL_PASSWORD,
> + "123456");
> +
> + super.prepareKdc();
> + }
> +
> + @Test
> + public void testKdc() {
> + TgtTicket tgt;
> + SgtTicket tkt;
> +
> + try {
> + tgt = getKrbClient().requestTgt(getClientPrincipal(),
> getClientPassword());
> + assertThat(tgt).isNotNull();
> +
> + tkt = getKrbClient().requestSgt(tgt, getServerPrincipal());
> + assertThat(tkt).isNotNull();
> + } catch (Exception e) {
> + Assert.fail("Exception occurred with good password. "
> + + e.toString());
> + }
> + }
> +}
>
> http://git-wip-us.apache.org/repos/asf/directory-kerby/
> blob/11089e86/kerby-backend/mysql-backend/src/test/java/
> org/apache/kerby/kerberos/kerb/identity/backend/MySQLBackendTest.java
> ----------------------------------------------------------------------
> diff --git a/kerby-backend/mysql-backend/src/test/java/org/apache/
> kerby/kerberos/kerb/identity/backend/MySQLBackendTest.java
> b/kerby-backend/mysql-backend/src/test/java/org/apache/
> kerby/kerberos/kerb/identity/backend/MySQLBackendTest.java
> new file mode 100644
> index 0000000..59f3500
> --- /dev/null
> +++ b/kerby-backend/mysql-backend/src/test/java/org/apache/
> kerby/kerberos/kerb/identity/backend/MySQLBackendTest.java
> @@ -0,0 +1,57 @@
> +/**
> + * 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.kerby.kerberos.kerb.identity.backend;
> +
> +import org.apache.kerby.config.Conf;
> +import org.apache.kerby.kerberos.kdc.identitybackend.MySQLConfKey;
> +import org.apache.kerby.kerberos.kdc.identitybackend.
> MySQLIdentityBackend;
> +import org.apache.kerby.kerberos.kerb.KrbException;
> +import org.junit.AfterClass;
> +import org.junit.BeforeClass;
> +
> +import java.io.File;
> +import java.io.IOException;
> +
> +public class MySQLBackendTest extends BackendTestBase {
> + private static File testDir = new
> +File(System.getProperty("test.dir",
> "target"));
> + private static File dbFile = new File(testDir,
> + "mysqlbackend.mv.db");
> +
> + @BeforeClass
> + public static void setup() throws KrbException, IOException {
> + Conf config = new Conf();
> + config.setString(MySQLConfKey.MYSQL_DRIVER, "org.h2.Driver");
> + config.setString(MySQLConfKey.MYSQL_URL,
> + "jdbc:h2:" + testDir.getCanonicalPath() +
> "/mysqlbackend;MODE=MySQL");
> + config.setString(MySQLConfKey.MYSQL_USER, "root");
> + config.setString(MySQLConfKey.MYSQL_PASSWORD, "123456");
> + backend = new MySQLIdentityBackend(config);
> + backend.initialize();
> + }
> +
> + @AfterClass
> + public static void tearDown() throws KrbException {
> + if (backend != null) {
> + backend.stop();
> + }
> + if (dbFile.exists() && !dbFile.delete()) {
> + System.err.println("Failed to delete the test database
> file.");
> + }
> + }
> +}
>
> http://git-wip-us.apache.org/repos/asf/directory-kerby/
> blob/11089e86/kerby-backend/pom.xml
> ----------------------------------------------------------------------
> diff --git a/kerby-backend/pom.xml b/kerby-backend/pom.xml index
> ef95b87..6ce432c 100644
> --- a/kerby-backend/pom.xml
> +++ b/kerby-backend/pom.xml
> @@ -53,6 +53,7 @@
> <module>ldap-backend</module>
> <module>mavibot-backend</module>
> <module>zookeeper-backend</module>
> + <module>mysql-backend</module>
> </modules>
> </profile>
> </profiles>
>
> http://git-wip-us.apache.org/repos/asf/directory-kerby/
> blob/11089e86/kerby-dist/kdc-dist/conf/backend.conf
> ----------------------------------------------------------------------
> diff --git a/kerby-dist/kdc-dist/conf/backend.conf
> b/kerby-dist/kdc-dist/conf/backend.conf
> index 2ead268..20134ef 100644
> --- a/kerby-dist/kdc-dist/conf/backend.conf
> +++ b/kerby-dist/kdc-dist/conf/backend.conf
> @@ -22,3 +22,7 @@ embedded_zk = false
> zk_host = 127.0.0.1
> zk_port = 2181
> data_dir = /tmp/zookeeper/data
> +mysql_driver = org.drizzle.jdbc.DrizzleDriver mysql_url =
> +jdbc:mysql:thin://127.0.0.1:3306/mysqlbackend?createDB=true
> +mysql_user = root
> +mysql_password = passwd
>
> http://git-wip-us.apache.org/repos/asf/directory-kerby/
> blob/11089e86/kerby-dist/kdc-dist/pom.xml
> ----------------------------------------------------------------------
> diff --git a/kerby-dist/kdc-dist/pom.xml b/kerby-dist/kdc-dist/pom.xml
> index 1766d28..3a5de2d 100644
> --- a/kerby-dist/kdc-dist/pom.xml
> +++ b/kerby-dist/kdc-dist/pom.xml
> @@ -89,6 +89,13 @@
> <version>${gson.version}</version>
> </dependency>
>
> + <!-- For mysql backend -->
> + <dependency>
> + <groupId>org.apache.kerby</groupId>
> + <artifactId>mysql-backend</artifactId>
> + <version>${project.version}</version>
> + </dependency>
> +
> <!-- For common and misc -->
> <dependency>
> <groupId>org.slf4j</groupId>
>
>
--
Colm O hEigeartaigh
Talend Community Coder
http://coders.talend.com
Re: directory-kerby git commit: DIRKRB-678 Implement MySQL identity
backend for KDC server.
Posted by Colm O hEigeartaigh <co...@apache.org>.
Hi Frank,
I'd like to suggest a few small changes to this commit:
a) The mysql-backend uses different versions for junit + Apache Directory
as defined in the parent pom. So instead of 2.0.0-M23 for Apache Directory
you can use ${apacheds.version}. You can remove the junit version + test
scope because it's defined in the root pom under dependencyManagement.
b) The Apache Directory API is only used to call on GeneralizedTime, but
this pulls in a large number of dependencies in the distribution. Can we
replace GeneralizedTime with something else, or just pull GeneralizedTime
into our project directly?
c) I think the mysql-backend dependency should be commented out in the
kerby-dist pom.
Colm.
On Mon, Jan 15, 2018 at 2:38 AM, <ze...@apache.org> wrote:
> Repository: directory-kerby
> Updated Branches:
> refs/heads/trunk 7b30a96ee -> 11089e869
>
>
> DIRKRB-678 Implement MySQL identity backend for KDC server.
>
>
> Project: http://git-wip-us.apache.org/repos/asf/directory-kerby/repo
> Commit: http://git-wip-us.apache.org/repos/asf/directory-kerby/
> commit/11089e86
> Tree: http://git-wip-us.apache.org/repos/asf/directory-kerby/tree/11089e86
> Diff: http://git-wip-us.apache.org/repos/asf/directory-kerby/diff/11089e86
>
> Branch: refs/heads/trunk
> Commit: 11089e86940723fb2ca5850504b93814b4e794ad
> Parents: 7b30a96
> Author: zenglinx <fr...@intel.com>
> Authored: Mon Jan 15 10:38:30 2018 +0800
> Committer: zenglinx <fr...@intel.com>
> Committed: Mon Jan 15 10:38:30 2018 +0800
>
> ----------------------------------------------------------------------
> kerby-backend/mysql-backend/pom.xml | 91 ++++
> .../kdc/identitybackend/MySQLConfKey.java | 52 +++
> .../identitybackend/MySQLIdentityBackend.java | 437 +++++++++++++++++++
> .../identity/backend/MySQLBackendKdcTest.java | 78 ++++
> .../kerb/identity/backend/MySQLBackendTest.java | 57 +++
> kerby-backend/pom.xml | 1 +
> kerby-dist/kdc-dist/conf/backend.conf | 4 +
> kerby-dist/kdc-dist/pom.xml | 7 +
> 8 files changed, 727 insertions(+)
> ----------------------------------------------------------------------
>
>
> http://git-wip-us.apache.org/repos/asf/directory-kerby/
> blob/11089e86/kerby-backend/mysql-backend/pom.xml
> ----------------------------------------------------------------------
> diff --git a/kerby-backend/mysql-backend/pom.xml
> b/kerby-backend/mysql-backend/pom.xml
> new file mode 100644
> index 0000000..d24335a
> --- /dev/null
> +++ b/kerby-backend/mysql-backend/pom.xml
> @@ -0,0 +1,91 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +<!--
> + Licensed 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. See accompanying LICENSE file.
> +-->
> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="
> http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://
> maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
> + <modelVersion>4.0.0</modelVersion>
> +
> + <parent>
> + <groupId>org.apache.kerby</groupId>
> + <artifactId>kerby-backend</artifactId>
> + <version>1.1.1-SNAPSHOT</version>
> + </parent>
> +
> + <artifactId>mysql-backend</artifactId>
> + <name>MySQL identity backend</name>
> + <description>MySQL identity backend</description>
> +
> + <dependencies>
> + <dependency>
> + <groupId>org.apache.directory.server</groupId>
> + <artifactId>apacheds-core-api</artifactId>
> + <version>2.0.0-M23</version>
> + </dependency>
> + <dependency>
> + <groupId>commons-dbutils</groupId>
> + <artifactId>commons-dbutils</artifactId>
> + <version>1.6</version>
> + </dependency>
> + <dependency>
> + <groupId>org.drizzle.jdbc</groupId>
> + <artifactId>drizzle-jdbc</artifactId>
> + <version>1.4</version>
> + </dependency>
> + <dependency>
> + <groupId>org.apache.kerby</groupId>
> + <artifactId>kerby-config</artifactId>
> + <version>${project.version}</version>
> + </dependency>
> + <dependency>
> + <groupId>org.apache.kerby</groupId>
> + <artifactId>kerb-core</artifactId>
> + <version>${project.version}</version>
> + </dependency>
> + <dependency>
> + <groupId>org.apache.kerby</groupId>
> + <artifactId>kerb-identity</artifactId>
> + <version>${project.version}</version>
> + </dependency>
> + <dependency>
> + <groupId>org.apache.kerby</groupId>
> + <artifactId>kerb-common</artifactId>
> + <version>${project.version}</version>
> + </dependency>
> + <dependency>
> + <groupId>junit</groupId>
> + <artifactId>junit</artifactId>
> + <version>4.11</version>
> + <scope>test</scope>
> + </dependency>
> + <dependency>
> + <groupId>com.h2database</groupId>
> + <artifactId>h2</artifactId>
> + <version>1.4.196</version>
> + <scope>test</scope>
> + </dependency>
> + <dependency>
> + <groupId>org.apache.kerby</groupId>
> + <artifactId>kerb-identity-test</artifactId>
> + <version>${project.version}</version>
> + <scope>test</scope>
> + </dependency>
> + <dependency>
> + <groupId>org.apache.kerby</groupId>
> + <artifactId>kerb-kdc-test</artifactId>
> + <version>${project.version}</version>
> + <type>test-jar</type>
> + <scope>test</scope>
> + </dependency>
> + </dependencies>
> +
> +</project>
> \ No newline at end of file
>
> http://git-wip-us.apache.org/repos/asf/directory-kerby/
> blob/11089e86/kerby-backend/mysql-backend/src/main/java/
> org/apache/kerby/kerberos/kdc/identitybackend/MySQLConfKey.java
> ----------------------------------------------------------------------
> diff --git a/kerby-backend/mysql-backend/src/main/java/org/apache/
> kerby/kerberos/kdc/identitybackend/MySQLConfKey.java
> b/kerby-backend/mysql-backend/src/main/java/org/apache/kerby/kerberos/kdc/
> identitybackend/MySQLConfKey.java
> new file mode 100644
> index 0000000..ce2ead6
> --- /dev/null
> +++ b/kerby-backend/mysql-backend/src/main/java/org/apache/
> kerby/kerberos/kdc/identitybackend/MySQLConfKey.java
> @@ -0,0 +1,52 @@
> +/**
> + * 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.kerby.kerberos.kdc.identitybackend;
> +
> +import org.apache.kerby.config.ConfigKey;
> +
> +/**
> + * Define all the MySQL backend related configuration items with default
> values.
> + */
> +public enum MySQLConfKey implements ConfigKey {
> + MYSQL_DRIVER("org.drizzle.jdbc.DrizzleDriver"),
> + MYSQL_URL("jdbc:mysql:thin://127.0.0.1:3306/mysqlbackend"),
> + MYSQL_USER("root"),
> + MYSQL_PASSWORD("passwd");
> +
> + private Object defaultValue;
> +
> + MySQLConfKey() {
> + this.defaultValue = null;
> + }
> +
> + MySQLConfKey(Object defaultValue) {
> + this.defaultValue = defaultValue;
> + }
> +
> + @Override
> + public String getPropertyKey() {
> + return name().toLowerCase();
> + }
> +
> + @Override
> + public Object getDefaultValue() {
> + return this.defaultValue;
> + }
> +}
>
> http://git-wip-us.apache.org/repos/asf/directory-kerby/
> blob/11089e86/kerby-backend/mysql-backend/src/main/java/
> org/apache/kerby/kerberos/kdc/identitybackend/MySQLIdentityBackend.java
> ----------------------------------------------------------------------
> diff --git a/kerby-backend/mysql-backend/src/main/java/org/apache/
> kerby/kerberos/kdc/identitybackend/MySQLIdentityBackend.java
> b/kerby-backend/mysql-backend/src/main/java/org/apache/kerby/kerberos/kdc/
> identitybackend/MySQLIdentityBackend.java
> new file mode 100644
> index 0000000..32ede90
> --- /dev/null
> +++ b/kerby-backend/mysql-backend/src/main/java/org/apache/
> kerby/kerberos/kdc/identitybackend/MySQLIdentityBackend.java
> @@ -0,0 +1,437 @@
> +/**
> + * 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.kerby.kerberos.kdc.identitybackend;
> +
> +import org.apache.commons.dbutils.DbUtils;
> +import org.apache.directory.api.util.GeneralizedTime;
> +import org.apache.kerby.config.Config;
> +import org.apache.kerby.kerberos.kerb.KrbException;
> +import org.apache.kerby.kerberos.kerb.identity.backend.
> AbstractIdentityBackend;
> +import org.apache.kerby.kerberos.kerb.request.KrbIdentity;
> +import org.apache.kerby.kerberos.kerb.type.KerberosTime;
> +import org.apache.kerby.kerberos.kerb.type.base.EncryptionKey;
> +import org.apache.kerby.kerberos.kerb.type.base.EncryptionType;
> +import org.slf4j.Logger;
> +import org.slf4j.LoggerFactory;
> +
> +import java.sql.Connection;
> +import java.sql.DriverManager;
> +import java.sql.PreparedStatement;
> +import java.sql.ResultSet;
> +import java.sql.SQLException;
> +import java.text.ParseException;
> +import java.util.ArrayList;
> +import java.util.List;
> +import java.util.Map;
> +import javax.sql.rowset.serial.SerialBlob;
> +
> +/**
> + * A MySQL based backend implementation.
> + */
> +public class MySQLIdentityBackend extends AbstractIdentityBackend {
> + private Connection connection;
> + private String driver;
> + private String url;
> + private String user;
> + private String password;
> + private static final Logger LOG = LoggerFactory.getLogger(
> MySQLIdentityBackend.class);
> + private String identityTable;
> + private String keyInfoTable;
> +
> + /**
> + * Constructing an instance using specified config that contains
> anything
> + * to be used to initialize an MySQL Backend.
> + * @param config . The config is used to config the backend.
> + */
> + public MySQLIdentityBackend(final Config config) {
> + setConfig(config);
> + }
> +
> + public MySQLIdentityBackend() { }
> +
> + /**
> + * Start the MySQL connection.
> + */
> + private void startConnection() throws KrbException {
> + try {
> + Class.forName(driver);
> + connection = DriverManager.getConnection(url, user,
> password);
> + if (!connection.isClosed()) {
> + LOG.info("Succeeded in connecting to MySQL.");
> + }
> + } catch (ClassNotFoundException e) {
> + throw new KrbException("JDBC Driver Class not found. ", e);
> + } catch (SQLException e) {
> + throw new KrbException("Failed to connecting to MySQL. ", e);
> + }
> + }
> +
> + /**
> + * {@inheritDoc}
> + */
> + @Override
> + protected void doInitialize() throws KrbException {
> + LOG.info("Initializing the MySQL identity backend.");
> + driver = getConfig().getString(MySQLConfKey.MYSQL_DRIVER, true);
> + user = getConfig().getString(MySQLConfKey.MYSQL_USER, true);
> + password = getConfig().getString(MySQLConfKey.MYSQL_PASSWORD,
> true);
> +
> + String urlString = getConfig().getString(MySQLConfKey.MYSQL_URL,
> true);
> + if (urlString == null || urlString.isEmpty()) {
> + urlString = getBackendConfig().getString(MySQLConfKey.MYSQL_URL,
> true);
> + }
> + url = urlString;
> +
> + ResultSet resCheckTable = null;
> + PreparedStatement preInitialize = null;
> + PreparedStatement preKdcRealm = null;
> + ResultSet resKdcRealm = null;
> + PreparedStatement preIdentity = null;
> + PreparedStatement preKey = null;
> + try {
> + startConnection();
> +
> + resCheckTable = connection.getMetaData().getTables(null,
> null, "kdc_config", null);
> + if (resCheckTable.next()) {
> + // Set initialized for kdc config table if HAS enabled
> + String stmInitialize = "UPDATE `kdc_config` SET
> initialized = true WHERE id = 1";
> + preInitialize = connection.prepareStatement(
> stmInitialize);
> + preInitialize.executeUpdate();
> +
> + // Get identity table name according to realm of kdc
> + String stmKdcRealm = "SELECT realm FROM `kdc_config`";
> + preKdcRealm = connection.prepareStatement(stmKdcRealm);
> + resKdcRealm = preKdcRealm.executeQuery();
> + if (resKdcRealm.next()) {
> + String realm = resKdcRealm.getString("realm")
> .toLowerCase();
> + identityTable = "`" + realm + "_identity" + "`";
> + keyInfoTable = "`" + realm + "_key" + "`";
> + } else {
> + throw new KrbException("Failed to get kdc config.");
> + }
> + } else {
> + identityTable = "`" + "kerby_identity" + "`";
> + keyInfoTable = "`" + "kerby_key" + "`";
> + }
> +
> + // Create identity table
> + String stmIdentity = "CREATE TABLE IF NOT EXISTS " +
> identityTable
> + + " (principal varchar(255) NOT NULL, key_version INTEGER
> "
> + + "DEFAULT 1, kdc_flags INTEGER DEFAULT 0, disabled bool "
> + + "DEFAULT NULL, locked bool DEFAULT NULL, created_time "
> + + "VARCHAR(255) DEFAULT NULL, expire_time VARCHAR(255) "
> + + "DEFAULT NULL, PRIMARY KEY (principal) ) ENGINE=INNODB "
> + + "DEFAULT CHARSET=utf8;";
> + preIdentity = connection.prepareStatement(stmIdentity);
> + preIdentity.executeUpdate();
> +
> + // Create key table
> + String stmKey = "CREATE TABLE IF NOT EXISTS " + keyInfoTable
> + + " (key_id INTEGER NOT NULL AUTO_INCREMENT, key_type "
> + + "VARCHAR(255) DEFAULT NULL, kvno INTEGER DEFAULT -1, "
> + + "key_value BLOB DEFAULT NULL, principal VARCHAR(255)
> NOT NULL,"
> + + "PRIMARY KEY (key_id), INDEX (principal), FOREIGN KEY "
> + + "(principal) REFERENCES " + identityTable +
> "(principal) "
> + + ") ENGINE=INNODB DEFAULT CHARSET=utf8;";
> + preKey = connection.prepareStatement(stmKey);
> + preKey.executeUpdate();
> +
> + } catch (SQLException e) {
> + LOG.error("Error occurred while initialize MySQL backend." +
> e.toString());
> + throw new KrbException("Failed to create table in database.
> ", e);
> + } finally {
> + DbUtils.closeQuietly(resCheckTable);
> + DbUtils.closeQuietly(preInitialize);
> + DbUtils.closeQuietly(preKdcRealm);
> + DbUtils.closeQuietly(resKdcRealm);
> + DbUtils.closeQuietly(preIdentity);
> + DbUtils.closeQuietly(preKey);
> + doStop();
> + }
> + }
> +
> + /**
> + * {@inheritDoc}
> + */
> + @Override
> + protected void doStop() throws KrbException {
> + try {
> + closeConnection();
> + if (connection.isClosed()) {
> + LOG.info("Succeeded in closing connection with MySQL.");
> + }
> + } catch (SQLException e) {
> + LOG.error("Failed to close connection with MySQL.");
> + throw new KrbException("Failed to close connection with
> MySQL. ", e);
> + }
> + }
> +
> + /**
> + * Close the connection for stop().
> + * @throws SQLException if SQLException handled
> + */
> + private void closeConnection() throws SQLException {
> + if (!connection.isClosed()) {
> + connection.close();
> + }
> + }
> +
> + /**
> + * Convert a KerberosTime type object to a generalized time form of
> String.
> + * @param kerberosTime The kerberos time to convert
> + */
> + private String toGeneralizedTime(final KerberosTime kerberosTime) {
> + GeneralizedTime generalizedTime = new
> GeneralizedTime(kerberosTime.getValue());
> + return generalizedTime.toString();
> + }
> +
> + /**
> + * {@inheritDoc}
> + */
> + @Override
> + protected KrbIdentity doAddIdentity(KrbIdentity identity) throws
> KrbException {
> + String principalName = identity.getPrincipalName();
> + int keyVersion = identity.getKeyVersion();
> + int kdcFlags = identity.getKdcFlags();
> + boolean disabled = identity.isDisabled();
> + boolean locked = identity.isLocked();
> + String createdTime = toGeneralizedTime(identity.
> getCreatedTime());
> + String expireTime = toGeneralizedTime(identity.getExpireTime());
> + Map<EncryptionType, EncryptionKey> keys = identity.getKeys();
> +
> + PreparedStatement preIdentity = null;
> + PreparedStatement preKey = null;
> +
> + KrbIdentity duplicateIdentity = doGetIdentity(principalName);
> + if (duplicateIdentity != null) {
> + LOG.warn("The identity maybe duplicate.");
> +
> + return duplicateIdentity;
> + } else {
> + try {
> + startConnection();
> + connection.setAutoCommit(false);
> +
> + // Insert identity to identity table
> + String stmIdentity = "insert into " + identityTable
> + + " (principal, key_version, kdc_flags, disabled,
> locked, created_time, expire_time)"
> + + " values(?, ?, ?, ?, ?, ?, ?)";
> + preIdentity = connection.prepareStatement(stmIdentity);
> + preIdentity.setString(1, principalName);
> + preIdentity.setInt(2, keyVersion);
> + preIdentity.setInt(3, kdcFlags);
> + preIdentity.setBoolean(4, disabled);
> + preIdentity.setBoolean(5, locked);
> + preIdentity.setString(6, createdTime);
> + preIdentity.setString(7, expireTime);
> + preIdentity.executeUpdate();
> +
> + // Insert keys to key table
> + for (Map.Entry<EncryptionType, EncryptionKey> entry :
> keys.entrySet()) {
> + String stmKey = "insert into " + keyInfoTable + "
> (key_type, kvno, key_value, principal)"
> + + " values(?, ?, ?, ?)";
> + preKey = connection.prepareStatement(stmKey);
> + preKey.setString(1, entry.getKey().getName());
> + preKey.setInt(2, entry.getValue().getKvno());
> + preKey.setBlob(3, new SerialBlob(entry.getValue().
> getKeyData()));
> + preKey.setString(4, principalName);
> + preKey.executeUpdate();
> + }
> +
> + connection.commit();
> + return identity;
> + } catch (SQLException e) {
> + try {
> + LOG.info("Transaction is being rolled back.");
> + connection.rollback();
> + } catch (SQLException ex) {
> + throw new KrbException("Transaction roll back failed.
> ", ex);
> + }
> + LOG.error("Error occurred while adding identity.");
> + throw new KrbException("Failed to add identity. ", e);
> + } finally {
> + DbUtils.closeQuietly(preIdentity);
> + DbUtils.closeQuietly(preKey);
> + doStop();
> + }
> + }
> + }
> +
> + /**
> + * Create kerberos time.
> + * @param generalizedTime generalized time
> + * @throws ParseException parse exception
> + */
> + private KerberosTime createKerberosTime(final String generalizedTime)
> throws ParseException {
> + long time = new GeneralizedTime(generalizedTime).getTime();
> + return new KerberosTime(time);
> + }
> +
> + /**
> + * {@inheritDoc}
> + */
> + @Override
> + protected KrbIdentity doGetIdentity(final String principalName)
> throws KrbException {
> + KrbIdentity krbIdentity = new KrbIdentity(principalName);
> +
> + PreparedStatement preIdentity = null;
> + ResultSet resIdentity = null;
> + PreparedStatement preKey = null;
> + ResultSet resKey = null;
> + try {
> + startConnection();
> +
> + // Get identity from identity table
> + String stmIdentity = "SELECT * FROM " + identityTable + "
> where principal = ?";
> + preIdentity = connection.prepareStatement(stmIdentity);
> + preIdentity.setString(1, principalName);
> + resIdentity = preIdentity.executeQuery();
> +
> + if (!resIdentity.isBeforeFirst()) {
> + return null;
> + }
> +
> + while (resIdentity.next()) {
> + krbIdentity.setKeyVersion(resIdentity.getInt("key_
> version"));
> + krbIdentity.setKdcFlags(resIdentity.getInt("kdc_flags"));
> + krbIdentity.setDisabled(resIdentity.getBoolean("
> disabled"));
> + krbIdentity.setLocked(resIdentity.getBoolean("locked"));
> + krbIdentity.setCreatedTime(createKerberosTime(
> resIdentity.getString("created_time")));
> + krbIdentity.setExpireTime(createKerberosTime(
> resIdentity.getString("expire_time")));
> + }
> +
> + // Get keys from key table
> + List<EncryptionKey> keys = new ArrayList<>();
> + String stmKey = "SELECT * FROM " + keyInfoTable + " where
> principal = ?";
> + preKey = connection.prepareStatement(stmKey);
> + preKey.setString(1, principalName);
> + resKey = preKey.executeQuery();
> + while (resKey.next()) {
> + int kvno = resKey.getInt("kvno");
> + String keyType = resKey.getString("key_type");
> + EncryptionType eType = EncryptionType.fromName(keyType);
> + byte[] keyValue = resKey.getBytes("key_value");
> + EncryptionKey key = new EncryptionKey(eType, keyValue,
> kvno);
> + keys.add(key);
> + }
> +
> + krbIdentity.addKeys(keys);
> + return krbIdentity;
> + } catch (SQLException e) {
> + LOG.error("Error occurred while getting identity.");
> + throw new KrbException("Failed to get identity. ", e);
> + } catch (ParseException e) {
> + throw new KrbException("Failed to get identity. ", e);
> + } finally {
> + DbUtils.closeQuietly(preIdentity);
> + DbUtils.closeQuietly(resIdentity);
> + DbUtils.closeQuietly(preKey);
> + DbUtils.closeQuietly(resKey);
> + doStop();
> + }
> + }
> +
> + /**
> + * {@inheritDoc}
> + */
> + @Override
> + protected KrbIdentity doUpdateIdentity(KrbIdentity identity) throws
> KrbException {
> + String principalName = identity.getPrincipalName();
> + try {
> + doDeleteIdentity(principalName); // Delete former identity
> + doAddIdentity(identity); // Insert new identity
> + } catch (KrbException e) {
> + LOG.error("Error occurred while updating identity: " +
> principalName);
> + throw new KrbException("Failed to update identity. ", e);
> + }
> +
> + return getIdentity(principalName);
> + }
> +
> + /**
> + * {@inheritDoc}
> + */
> + @Override
> + protected void doDeleteIdentity(String principalName) throws
> KrbException {
> + PreparedStatement preKey = null;
> + PreparedStatement preIdentity = null;
> + try {
> + startConnection();
> + connection.setAutoCommit(false);
> +
> + // Delete keys from key table
> + String stmKey = "DELETE FROM " + keyInfoTable + " where
> principal = ?";
> + preKey = connection.prepareStatement(stmKey);
> + preKey.setString(1, principalName);
> + preKey.executeUpdate();
> +
> + // Dlete identity from identity table
> + String stmIdentity = "DELETE FROM " + identityTable + " where
> principal = ? ";
> + preIdentity = connection.prepareStatement(stmIdentity);
> + preIdentity.setString(1, principalName);
> + preIdentity.executeUpdate();
> +
> + connection.commit();
> + } catch (SQLException e) {
> + try {
> + LOG.info("Transaction is being rolled back.");
> + connection.rollback();
> + } catch (SQLException ex) {
> + throw new KrbException("Transaction roll back failed. ",
> ex);
> + }
> + LOG.error("Error occurred while deleting identity.");
> + throw new KrbException("Failed to delete identity. ", e);
> + } finally {
> + DbUtils.closeQuietly(preIdentity);
> + DbUtils.closeQuietly(preKey);
> + doStop();
> + }
> + }
> +
> + /**
> + * {@inheritDoc}
> + */
> + @Override
> + protected Iterable<String> doGetIdentities() throws KrbException {
> + List<String> identityNames = new ArrayList<>();
> + PreparedStatement preSmt = null;
> + ResultSet result = null;
> + try {
> + startConnection();
> + String statement = "SELECT * FROM " + identityTable;
> + preSmt = connection.prepareStatement(statement);
> + result = preSmt.executeQuery();
> + while (result.next()) {
> + identityNames.add(result.getString("principal"));
> + }
> + result.close();
> + preSmt.close();
> + } catch (SQLException e) {
> + LOG.error("Error occurred while getting identities.");
> + throw new KrbException("Failed to get identities. ", e);
> + } finally {
> + DbUtils.closeQuietly(preSmt);
> + DbUtils.closeQuietly(result);
> + doStop();
> + }
> +
> + return identityNames;
> + }
> +}
>
> http://git-wip-us.apache.org/repos/asf/directory-kerby/
> blob/11089e86/kerby-backend/mysql-backend/src/test/java/
> org/apache/kerby/kerberos/kerb/identity/backend/MySQLBackendKdcTest.java
> ----------------------------------------------------------------------
> diff --git a/kerby-backend/mysql-backend/src/test/java/org/apache/
> kerby/kerberos/kerb/identity/backend/MySQLBackendKdcTest.java
> b/kerby-backend/mysql-backend/src/test/java/org/apache/
> kerby/kerberos/kerb/identity/backend/MySQLBackendKdcTest.java
> new file mode 100644
> index 0000000..565a0ee
> --- /dev/null
> +++ b/kerby-backend/mysql-backend/src/test/java/org/apache/
> kerby/kerberos/kerb/identity/backend/MySQLBackendKdcTest.java
> @@ -0,0 +1,78 @@
> +/**
> + * 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.kerby.kerberos.kerb.identity.backend;
> +
> +import org.apache.kerby.kerberos.kdc.identitybackend.MySQLConfKey;
> +import org.apache.kerby.kerberos.kerb.KrbException;
> +import org.apache.kerby.kerberos.kerb.server.KdcConfigKey;
> +import org.apache.kerby.kerberos.kerb.server.KdcTestBase;
> +import org.apache.kerby.kerberos.kerb.type.ticket.SgtTicket;
> +import org.apache.kerby.kerberos.kerb.type.ticket.TgtTicket;
> +import org.junit.After;
> +import org.junit.Assert;
> +import org.junit.Test;
> +
> +import java.io.File;
> +
> +import static org.assertj.core.api.Assertions.assertThat;
> +
> +public class MySQLBackendKdcTest extends KdcTestBase {
> + private static File testDir = new File(System.getProperty("test.dir",
> "target"));
> + private static File dbFile = new File(testDir, "mysqlbackend.mv.db");
> +
> + @After
> + public void tearDown() {
> + if (dbFile.exists() && !dbFile.delete()) {
> + System.err.println("Failed to delete the test database
> file.");
> + }
> + }
> +
> + @Override
> + protected void prepareKdc() throws KrbException {
> + BackendConfig backendConfig = getKdcServer().getBackendConfig();
> +
> + backendConfig.setString(KdcConfigKey.KDC_IDENTITY_BACKEND,
> + "org.apache.kerby.kerberos.kdc.identitybackend.
> MySQLIdentityBackend");
> + backendConfig.setString(MySQLConfKey.MYSQL_DRIVER,
> "org.h2.Driver");
> + backendConfig.setString(MySQLConfKey.MYSQL_URL,
> + "jdbc:h2:" + testDir.getAbsolutePath() +
> "/mysqlbackend;MODE=MySQL");
> + backendConfig.setString(MySQLConfKey.MYSQL_USER, "root");
> + backendConfig.setString(MySQLConfKey.MYSQL_PASSWORD, "123456");
> +
> + super.prepareKdc();
> + }
> +
> + @Test
> + public void testKdc() {
> + TgtTicket tgt;
> + SgtTicket tkt;
> +
> + try {
> + tgt = getKrbClient().requestTgt(getClientPrincipal(),
> getClientPassword());
> + assertThat(tgt).isNotNull();
> +
> + tkt = getKrbClient().requestSgt(tgt, getServerPrincipal());
> + assertThat(tkt).isNotNull();
> + } catch (Exception e) {
> + Assert.fail("Exception occurred with good password. "
> + + e.toString());
> + }
> + }
> +}
>
> http://git-wip-us.apache.org/repos/asf/directory-kerby/
> blob/11089e86/kerby-backend/mysql-backend/src/test/java/
> org/apache/kerby/kerberos/kerb/identity/backend/MySQLBackendTest.java
> ----------------------------------------------------------------------
> diff --git a/kerby-backend/mysql-backend/src/test/java/org/apache/
> kerby/kerberos/kerb/identity/backend/MySQLBackendTest.java
> b/kerby-backend/mysql-backend/src/test/java/org/apache/
> kerby/kerberos/kerb/identity/backend/MySQLBackendTest.java
> new file mode 100644
> index 0000000..59f3500
> --- /dev/null
> +++ b/kerby-backend/mysql-backend/src/test/java/org/apache/
> kerby/kerberos/kerb/identity/backend/MySQLBackendTest.java
> @@ -0,0 +1,57 @@
> +/**
> + * 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.kerby.kerberos.kerb.identity.backend;
> +
> +import org.apache.kerby.config.Conf;
> +import org.apache.kerby.kerberos.kdc.identitybackend.MySQLConfKey;
> +import org.apache.kerby.kerberos.kdc.identitybackend.
> MySQLIdentityBackend;
> +import org.apache.kerby.kerberos.kerb.KrbException;
> +import org.junit.AfterClass;
> +import org.junit.BeforeClass;
> +
> +import java.io.File;
> +import java.io.IOException;
> +
> +public class MySQLBackendTest extends BackendTestBase {
> + private static File testDir = new File(System.getProperty("test.dir",
> "target"));
> + private static File dbFile = new File(testDir, "mysqlbackend.mv.db");
> +
> + @BeforeClass
> + public static void setup() throws KrbException, IOException {
> + Conf config = new Conf();
> + config.setString(MySQLConfKey.MYSQL_DRIVER, "org.h2.Driver");
> + config.setString(MySQLConfKey.MYSQL_URL,
> + "jdbc:h2:" + testDir.getCanonicalPath() +
> "/mysqlbackend;MODE=MySQL");
> + config.setString(MySQLConfKey.MYSQL_USER, "root");
> + config.setString(MySQLConfKey.MYSQL_PASSWORD, "123456");
> + backend = new MySQLIdentityBackend(config);
> + backend.initialize();
> + }
> +
> + @AfterClass
> + public static void tearDown() throws KrbException {
> + if (backend != null) {
> + backend.stop();
> + }
> + if (dbFile.exists() && !dbFile.delete()) {
> + System.err.println("Failed to delete the test database
> file.");
> + }
> + }
> +}
>
> http://git-wip-us.apache.org/repos/asf/directory-kerby/
> blob/11089e86/kerby-backend/pom.xml
> ----------------------------------------------------------------------
> diff --git a/kerby-backend/pom.xml b/kerby-backend/pom.xml
> index ef95b87..6ce432c 100644
> --- a/kerby-backend/pom.xml
> +++ b/kerby-backend/pom.xml
> @@ -53,6 +53,7 @@
> <module>ldap-backend</module>
> <module>mavibot-backend</module>
> <module>zookeeper-backend</module>
> + <module>mysql-backend</module>
> </modules>
> </profile>
> </profiles>
>
> http://git-wip-us.apache.org/repos/asf/directory-kerby/
> blob/11089e86/kerby-dist/kdc-dist/conf/backend.conf
> ----------------------------------------------------------------------
> diff --git a/kerby-dist/kdc-dist/conf/backend.conf
> b/kerby-dist/kdc-dist/conf/backend.conf
> index 2ead268..20134ef 100644
> --- a/kerby-dist/kdc-dist/conf/backend.conf
> +++ b/kerby-dist/kdc-dist/conf/backend.conf
> @@ -22,3 +22,7 @@ embedded_zk = false
> zk_host = 127.0.0.1
> zk_port = 2181
> data_dir = /tmp/zookeeper/data
> +mysql_driver = org.drizzle.jdbc.DrizzleDriver
> +mysql_url = jdbc:mysql:thin://127.0.0.1:3306/mysqlbackend?createDB=true
> +mysql_user = root
> +mysql_password = passwd
>
> http://git-wip-us.apache.org/repos/asf/directory-kerby/
> blob/11089e86/kerby-dist/kdc-dist/pom.xml
> ----------------------------------------------------------------------
> diff --git a/kerby-dist/kdc-dist/pom.xml b/kerby-dist/kdc-dist/pom.xml
> index 1766d28..3a5de2d 100644
> --- a/kerby-dist/kdc-dist/pom.xml
> +++ b/kerby-dist/kdc-dist/pom.xml
> @@ -89,6 +89,13 @@
> <version>${gson.version}</version>
> </dependency>
>
> + <!-- For mysql backend -->
> + <dependency>
> + <groupId>org.apache.kerby</groupId>
> + <artifactId>mysql-backend</artifactId>
> + <version>${project.version}</version>
> + </dependency>
> +
> <!-- For common and misc -->
> <dependency>
> <groupId>org.slf4j</groupId>
>
>
--
Colm O hEigeartaigh
Talend Community Coder
http://coders.talend.com