You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by pl...@apache.org on 2018/07/06 06:29:24 UTC
directory-kerby git commit: DIRKRB-722 Add HAS client login tool.
Repository: directory-kerby
Updated Branches:
refs/heads/trunk 5ec8b2053 -> 9a02da485
DIRKRB-722 Add HAS client login tool.
Project: http://git-wip-us.apache.org/repos/asf/directory-kerby/repo
Commit: http://git-wip-us.apache.org/repos/asf/directory-kerby/commit/9a02da48
Tree: http://git-wip-us.apache.org/repos/asf/directory-kerby/tree/9a02da48
Diff: http://git-wip-us.apache.org/repos/asf/directory-kerby/diff/9a02da48
Branch: refs/heads/trunk
Commit: 9a02da4859ccf94b5ba08567aeca488f109479c6
Parents: 5ec8b20
Author: plusplusjiajia <ji...@intel.com>
Authored: Fri Jul 6 14:29:16 2018 +0800
Committer: plusplusjiajia <ji...@intel.com>
Committed: Fri Jul 6 14:29:16 2018 +0800
----------------------------------------------------------------------
.../apache/kerby/has/common/HasConfigKey.java | 2 +-
.../kerby/has/common/util/HasJaasLoginUtil.java | 110 ++++++++
.../apache/kerby/has/common/util/HasUtil.java | 2 +-
kerby-dist/has-dist/bin/admin-local.sh | 2 +-
kerby-dist/has-dist/bin/login-test.sh | 34 +++
.../tool/hclient/HasClientLoginTool.java | 272 +++++++++++++++++++
6 files changed, 419 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9a02da48/has-project/has-common/src/main/java/org/apache/kerby/has/common/HasConfigKey.java
----------------------------------------------------------------------
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/HasConfigKey.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/HasConfigKey.java
index 272ab0e..d4cc474 100644
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/HasConfigKey.java
+++ b/has-project/has-common/src/main/java/org/apache/kerby/has/common/HasConfigKey.java
@@ -26,7 +26,7 @@ public enum HasConfigKey implements ConfigKey {
HTTP_PORT,
HTTPS_HOST,
HTTPS_PORT,
- AUTH_TYPE("RAM"),
+ AUTH_TYPE("MySQL"),
REALM,
ENABLE_CONF,
SSL_SERVER_CONF("/etc/has/ssl-server.conf"),
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9a02da48/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/HasJaasLoginUtil.java
----------------------------------------------------------------------
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/HasJaasLoginUtil.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/HasJaasLoginUtil.java
new file mode 100644
index 0000000..a4c9590
--- /dev/null
+++ b/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/HasJaasLoginUtil.java
@@ -0,0 +1,110 @@
+/**
+ * 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.has.common.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * JAAS utilities for Has login.
+ */
+public class HasJaasLoginUtil {
+ public static final Logger LOG = LoggerFactory.getLogger(HasJaasLoginUtil.class);
+
+ public static final boolean ENABLE_DEBUG = true;
+
+ private static String getKrb5LoginModuleName() {
+ return System.getProperty("java.vendor").contains("IBM")
+ ? "com.ibm.security.auth.module.Krb5LoginModule"
+ : "org.apache.kerby.has.client.HasLoginModule";
+ }
+
+ /**
+ * Log a user in from a tgt ticket.
+ *
+ * @throws IOException
+ */
+ public static synchronized Subject loginUserFromTgtTicket(String hadoopSecurityHas) throws IOException {
+
+ TICKET_KERBEROS_OPTIONS.put("hadoopSecurityHas", hadoopSecurityHas);
+ Subject subject = new Subject();
+ Configuration conf = new HasJaasConf();
+ String confName = "ticket-kerberos";
+ LoginContext loginContext = null;
+ try {
+ loginContext = new LoginContext(confName, subject, null, conf);
+ } catch (LoginException e) {
+ throw new IOException("Fail to create LoginContext for " + e);
+ }
+ try {
+ loginContext.login();
+ LOG.info("Login successful for user "
+ + subject.getPrincipals().iterator().next().getName());
+ } catch (LoginException e) {
+ throw new IOException("Login failure for " + e);
+ }
+ return loginContext.getSubject();
+ }
+
+ /**
+ * Has Jaas config.
+ */
+ static class HasJaasConf extends Configuration {
+ @Override
+ public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
+
+ return new AppConfigurationEntry[]{
+ TICKET_KERBEROS_LOGIN};
+ }
+ }
+
+ private static final Map<String, String> BASIC_JAAS_OPTIONS =
+ new HashMap<String, String>();
+
+ static {
+ String jaasEnvVar = System.getenv("HADOOP_JAAS_DEBUG");
+ if (jaasEnvVar != null && "true".equalsIgnoreCase(jaasEnvVar)) {
+ BASIC_JAAS_OPTIONS.put("debug", String.valueOf(ENABLE_DEBUG));
+ }
+ }
+
+ private static final Map<String, String> TICKET_KERBEROS_OPTIONS =
+ new HashMap<String, String>();
+
+ static {
+ TICKET_KERBEROS_OPTIONS.put("doNotPrompt", "true");
+ TICKET_KERBEROS_OPTIONS.put("useTgtTicket", "true");
+ TICKET_KERBEROS_OPTIONS.putAll(BASIC_JAAS_OPTIONS);
+ }
+
+ private static final AppConfigurationEntry TICKET_KERBEROS_LOGIN =
+ new AppConfigurationEntry(getKrb5LoginModuleName(),
+ AppConfigurationEntry.LoginModuleControlFlag.OPTIONAL,
+ TICKET_KERBEROS_OPTIONS);
+}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9a02da48/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/HasUtil.java
----------------------------------------------------------------------
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/HasUtil.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/HasUtil.java
index 6b01058..c972955 100644
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/HasUtil.java
+++ b/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/HasUtil.java
@@ -51,7 +51,7 @@ public class HasUtil {
}
return hasConfig;
} else {
- throw new HasException(hasConfFile.getName() + "not found in "
+ throw new HasException(hasConfFile.getName() + " not found in "
+ hasConfFile.getParent() + ". ");
}
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9a02da48/kerby-dist/has-dist/bin/admin-local.sh
----------------------------------------------------------------------
diff --git a/kerby-dist/has-dist/bin/admin-local.sh b/kerby-dist/has-dist/bin/admin-local.sh
index 1b0cc67..84b3918 100644
--- a/kerby-dist/has-dist/bin/admin-local.sh
+++ b/kerby-dist/has-dist/bin/admin-local.sh
@@ -42,7 +42,7 @@ cd ${HAS_HOME}
for var in $*; do
if [ X"$var" = X"-D" ]; then
- DEBUG="-Xdebug -Xrunjdwp:transport=dt_socket,address=8002,server=y,suspend=n"
+ DEBUG="-Xdebug -Xrunjdwp:transport=dt_socket,address=8013,server=y,suspend=n"
elif [ ! -d "$var" ]; then
args="$args $var"
fi
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9a02da48/kerby-dist/has-dist/bin/login-test.sh
----------------------------------------------------------------------
diff --git a/kerby-dist/has-dist/bin/login-test.sh b/kerby-dist/has-dist/bin/login-test.sh
new file mode 100644
index 0000000..4db4dcf
--- /dev/null
+++ b/kerby-dist/has-dist/bin/login-test.sh
@@ -0,0 +1,34 @@
+#!/usr/bin/env bash
+
+# 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.
+
+APP_MAIN=org.apache.kerby.kerberos.tool.hclient.HasClientLoginTool
+
+# Get HAS_HOME directory
+bin=`dirname "$0"`
+HAS_HOME=`cd ${bin}/..; pwd`
+cd ${HAS_HOME}
+
+for var in $*; do
+ if [ X"$var" = X"-D" ]; then
+ DEBUG="-Xdebug -Xrunjdwp:transport=dt_socket,address=8014,server=y,suspend=y"
+ else
+ args="$args $var"
+ fi
+done
+
+java ${DEBUG} -classpath target/lib/*:. ${APP_MAIN} ${args}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9a02da48/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/hclient/HasClientLoginTool.java
----------------------------------------------------------------------
diff --git a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/hclient/HasClientLoginTool.java b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/hclient/HasClientLoginTool.java
new file mode 100644
index 0000000..a49a7e7
--- /dev/null
+++ b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/hclient/HasClientLoginTool.java
@@ -0,0 +1,272 @@
+/**
+ * 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.tool.hclient;
+
+import org.apache.kerby.has.client.HasAuthAdminClient;
+import org.apache.kerby.has.client.HasClient;
+import org.apache.kerby.has.common.HasConfig;
+import org.apache.kerby.has.common.HasException;
+import org.apache.kerby.has.common.util.HasJaasLoginUtil;
+import org.apache.kerby.has.common.util.HasUtil;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.client.JaasKrbUtil;
+import org.apache.kerby.kerberos.kerb.server.KdcConfig;
+import org.apache.kerby.kerberos.kerb.server.KdcUtil;
+import org.apache.kerby.kerberos.kerb.type.ticket.TgtTicket;
+import org.apache.kerby.util.OSUtil;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginException;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+public class HasClientLoginTool {
+ private static List<String> principalList = new ArrayList<String>();
+ private static List<File> keytabList = new ArrayList<File>();
+
+ private static final String KEYTAB_USAGE = (OSUtil.isWindows()
+ ? "Usage: bin\\k=login-test.cmd" : "Usage: sh bin/login-test.sh")
+ + " [add|run|delete] [conf_dir] [work_dir] [number]\n"
+ + "\n";
+
+ private static final String TGT_USAGE = (OSUtil.isWindows()
+ ? "Usage: bin\\k=login-test.cmd" : "Usage: sh bin/login-test.sh")
+ + " tgt [conf_dir]\n"
+ + "\n";
+
+ private static void printKeytabUsage(String error) {
+ System.err.println(error + "\n");
+ System.err.println(KEYTAB_USAGE);
+ System.exit(-1);
+ }
+
+ private static void printTgtUsage(String error) {
+ System.err.println(error + "\n");
+ System.err.println(TGT_USAGE);
+ System.exit(-1);
+ }
+
+ public static class Task implements Runnable {
+ private int index;
+
+ Task(int index) {
+ this.index = index;
+ }
+
+ @Override
+ public void run() {
+ Subject subject = null;
+ try {
+ subject = JaasKrbUtil.loginUsingKeytab(principalList.get(index),
+ keytabList.get(index));
+ } catch (LoginException e) {
+ System.err.println("Fail to login using keytab. " + e);
+ }
+ System.out.println("Login succeeded for user: "
+ + subject.getPrincipals().iterator().next());
+ }
+ }
+
+ public static void main(String[] args) {
+
+ if (args.length < 2) {
+ System.err.println(TGT_USAGE);
+ System.err.println(KEYTAB_USAGE);
+ return;
+ }
+
+ String cmd = args[0];
+ File confDir;
+ File workDir;
+
+ if (cmd.equals("tgt")) {
+ if (args.length != 2) {
+ printTgtUsage("Need 2 args.");
+ return;
+ }
+
+ confDir = new File(args[1]);
+ if (!confDir.exists()) {
+ printTgtUsage("Need the valid conf dir.");
+ return;
+ }
+ File confFile = new File(confDir, "admin.conf");
+ HasConfig hasConfig;
+ try {
+ hasConfig = HasUtil.getHasConfig(confFile);
+ } catch (HasException e) {
+ System.err.println(e.getMessage());
+ return;
+ }
+ if (hasConfig == null) {
+ System.err.println("admin.conf not exist in " + confDir.getAbsolutePath());
+ return;
+ }
+ String host = hasConfig.getHttpsHost();
+ String port = hasConfig.getHttpsPort();
+ String type = hasConfig.getPluginName();
+
+ HasClient hasClient = new HasClient();
+ TgtTicket tgtTicket;
+ try {
+ tgtTicket = hasClient.requestTgt();
+ } catch (HasException e) {
+ System.err.println("Errors occurred when getting TGT. " + e.getMessage());
+ return;
+ }
+
+ System.out.println("Get the tgt ticket successfully!");
+ System.out.println("The client principal of tgt ticket: " + tgtTicket.getClientPrincipal());
+
+ Subject subject = null;
+ try {
+ subject = HasJaasLoginUtil.loginUserFromTgtTicket(
+ "https://" + host + ":" + port + "/has/v1?auth_type=" + type);
+ } catch (IOException e) {
+ System.err.println("Errors occurred when login user with TGT. " + e.getMessage());
+ return;
+ }
+
+ System.out.println("Principal: " + subject.getPrincipals().iterator().next());
+ } else {
+ if (args.length != 4) {
+ printKeytabUsage("Need 4 args.");
+ return;
+ }
+
+ confDir = new File(args[1]);
+ workDir = new File(args[2]);
+
+ if (!confDir.exists()) {
+ printKeytabUsage("Need the valid conf dir.");
+ return;
+ }
+ if (!workDir.exists()) {
+ printKeytabUsage("Need the valid work dir.");
+ return;
+ }
+
+ int taskNum = Integer.parseInt(args[3]);
+
+ System.out.println("The task num is: " + taskNum);
+
+ if (taskNum <= 0) {
+ printKeytabUsage("The task num must be greater than zero");
+ System.exit(-1);
+ }
+
+ HasAuthAdminClient authHasAdminClient = null;
+ File confFile = new File(confDir, "admin.conf");
+ HasConfig hasConfig = null;
+ try {
+ hasConfig = HasUtil.getHasConfig(confFile);
+ } catch (HasException e) {
+ System.err.println(e.getMessage());
+ return;
+ }
+
+ if (hasConfig == null) {
+ System.err.println("admin.conf not exist in " + confDir.getAbsolutePath());
+ return;
+ }
+
+ if (hasConfig.getFilterAuthType().equals("kerberos")) {
+ authHasAdminClient = new HasAuthAdminClient(hasConfig);
+ }
+
+ String realm = null;
+ try {
+ KdcConfig kdcConfig = KdcUtil.getKdcConfig(confDir);
+ realm = kdcConfig.getKdcRealm();
+ } catch (KrbException e) {
+ printKeytabUsage(e.getMessage());
+ }
+
+ if (cmd.equals("add")) {
+ for (int i = 0; i < taskNum; i++) {
+ String principal = "test" + i + "@" + realm;
+ try {
+ authHasAdminClient.addPrincipal(principal);
+ } catch (KrbException e) {
+ System.err.println("Errors occurred when adding principal. "
+ + e.getMessage());
+ return;
+ }
+ File keytabFile = new File(workDir, i + ".keytab");
+ try {
+ authHasAdminClient.exportKeytab(keytabFile, principal);
+ } catch (KrbException e) {
+ System.err.println("Errors occurred when exporting the keytabs. "
+ + e.getMessage());
+ return;
+ }
+ System.out.println("Add principals and keytabs successfully.");
+ }
+ } else if (cmd.equals("run")) {
+ ExecutorService exec;
+ for (int i = 0; i < taskNum; i++) {
+ String principal = "test" + i + "@" + realm;
+ principalList.add(i, principal);
+ File file = new File(workDir, i + ".keytab");
+ keytabList.add(i, file);
+ }
+ System.out.println("Start the login test.");
+ Long startTime = System.currentTimeMillis();
+ exec = Executors.newFixedThreadPool(5);
+ for (int i = 0; i < taskNum; ++i) {
+ exec.submit(new Task(i));
+ }
+ exec.shutdown();
+ try {
+ exec.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
+ } catch (InterruptedException e) {
+ System.err.println(e.getMessage());
+ return;
+ }
+ Long endTime = System.currentTimeMillis();
+ System.out.println("Finish the login test.");
+ System.out.println("Cost time: " + (endTime - startTime) + "ms");
+ } else if (cmd.equals("delete")) {
+ for (int i = 0; i < taskNum; i++) {
+ String principal = "test" + i + "@" + realm;
+ try {
+ authHasAdminClient.deletePrincipal(principal);
+ } catch (KrbException e) {
+ System.err.println("Errors occurred when deleting the principal. "
+ + e.getMessage());
+ continue;
+ }
+ File file = new File(workDir, i + ".keytab");
+ if (!file.delete()) {
+ System.err.println("Failed to delete " + i + ".keytab.");
+ }
+ }
+ System.out.println("Delete principals and keytabs successfully.");
+ } else {
+ printKeytabUsage("Need the cmd with add, run or delete.");
+ }
+ }
+ }
+}