1 /** 2 * Licensed under the Apache License, Version 2.0 (the "License"); 3 * you may not use this file except in compliance with the License. 4 * You may obtain a copy of the License at 5 * 6 * http://www.apache.org/licenses/LICENSE-2.0 7 * 8 * Unless required by applicable law or agreed to in writing, software 9 * distributed under the License is distributed on an "AS IS" BASIS, 10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 * See the License for the specific language governing permissions and 12 * limitations under the License. See accompanying LICENSE file. 13 */ 14 package org.apache.hadoop.test; 15 16 import javax.security.auth.Subject; 17 import javax.security.auth.kerberos.KerberosPrincipal; 18 import javax.security.auth.login.AppConfigurationEntry; 19 import javax.security.auth.login.Configuration; 20 import javax.security.auth.login.LoginContext; 21 22 import org.apache.hadoop.security.authentication.util.KerberosUtil; 23 24 import java.io.File; 25 import java.security.Principal; 26 import java.security.PrivilegedActionException; 27 import java.security.PrivilegedExceptionAction; 28 import java.util.HashMap; 29 import java.util.HashSet; 30 import java.util.Map; 31 import java.util.Set; 32 import java.util.concurrent.Callable; 33 34 /** 35 * Test helper class for Java Kerberos setup. 36 */ 37 public class KerberosTestUtils { 38 private static final String PREFIX = "httpfs.test."; 39 40 public static final String REALM = PREFIX + "kerberos.realm"; 41 42 public static final String CLIENT_PRINCIPAL = 43 PREFIX + "kerberos.client.principal"; 44 45 public static final String SERVER_PRINCIPAL = 46 PREFIX + "kerberos.server.principal"; 47 48 public static final String KEYTAB_FILE = PREFIX + "kerberos.keytab.file"; 49 getRealm()50 public static String getRealm() { 51 return System.getProperty(REALM, "LOCALHOST"); 52 } 53 getClientPrincipal()54 public static String getClientPrincipal() { 55 return System.getProperty(CLIENT_PRINCIPAL, "client") + "@" + getRealm(); 56 } 57 getServerPrincipal()58 public static String getServerPrincipal() { 59 return System.getProperty(SERVER_PRINCIPAL, 60 "HTTP/localhost") + "@" + getRealm(); 61 } 62 getKeytabFile()63 public static String getKeytabFile() { 64 String keytabFile = 65 new File(System.getProperty("user.home"), 66 System.getProperty("user.name") + ".keytab").toString(); 67 return System.getProperty(KEYTAB_FILE, keytabFile); 68 } 69 70 private static class KerberosConfiguration extends Configuration { 71 private String principal; 72 KerberosConfiguration(String principal)73 public KerberosConfiguration(String principal) { 74 this.principal = principal; 75 } 76 77 @Override getAppConfigurationEntry(String name)78 public AppConfigurationEntry[] getAppConfigurationEntry(String name) { 79 Map<String, String> options = new HashMap<String, String>(); 80 options.put("keyTab", KerberosTestUtils.getKeytabFile()); 81 options.put("principal", principal); 82 options.put("useKeyTab", "true"); 83 options.put("storeKey", "true"); 84 options.put("doNotPrompt", "true"); 85 options.put("useTicketCache", "true"); 86 options.put("renewTGT", "true"); 87 options.put("refreshKrb5Config", "true"); 88 options.put("isInitiator", "true"); 89 String ticketCache = System.getenv("KRB5CCNAME"); 90 if (ticketCache != null) { 91 options.put("ticketCache", ticketCache); 92 } 93 options.put("debug", "true"); 94 95 return new AppConfigurationEntry[]{ 96 new AppConfigurationEntry(KerberosUtil.getKrb5LoginModuleName(), 97 AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, 98 options),}; 99 } 100 } 101 doAs(String principal, final Callable<T> callable)102 public static <T> T doAs(String principal, final Callable<T> callable) 103 throws Exception { 104 LoginContext loginContext = null; 105 try { 106 Set<Principal> principals = new HashSet<Principal>(); 107 principals.add( 108 new KerberosPrincipal(KerberosTestUtils.getClientPrincipal())); 109 Subject subject = new Subject(false, principals, new HashSet<Object>(), 110 new HashSet<Object>()); 111 loginContext = new LoginContext("", subject, null, 112 new KerberosConfiguration(principal)); 113 loginContext.login(); 114 subject = loginContext.getSubject(); 115 return Subject.doAs(subject, new PrivilegedExceptionAction<T>() { 116 @Override 117 public T run() throws Exception { 118 return callable.call(); 119 } 120 }); 121 } catch (PrivilegedActionException ex) { 122 throw ex.getException(); 123 } finally { 124 if (loginContext != null) { 125 loginContext.logout(); 126 } 127 } 128 } 129 130 public static <T> T doAsClient(Callable<T> callable) throws Exception { 131 return doAs(getClientPrincipal(), callable); 132 } 133 134 public static <T> T doAsServer(Callable<T> callable) throws Exception { 135 return doAs(getServerPrincipal(), callable); 136 } 137 138 } 139