/** * 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.hive.service.auth; import java.io.IOException; import java.util.Map; import javax.security.sasl.SaslException; import org.apache.hadoop.hive.shims.ShimLoader; import org.apache.hadoop.hive.thrift.HadoopThriftAuthBridge; import org.apache.hadoop.hive.thrift.HadoopThriftAuthBridge.Server; import org.apache.hive.service.cli.thrift.ThriftCLIService; import org.apache.hive.service.rpc.thrift.TCLIService; import org.apache.hive.service.rpc.thrift.TCLIService.Iface; import org.apache.thrift.TProcessor; import org.apache.thrift.TProcessorFactory; import org.apache.thrift.transport.TSaslClientTransport; import org.apache.thrift.transport.TTransport; public final class KerberosSaslHelper { public static TProcessorFactory getKerberosProcessorFactory(Server saslServer, ThriftCLIService service) { return new CLIServiceProcessorFactory(saslServer, service); } public static TTransport getKerberosTransport(String principal, String host, TTransport underlyingTransport, Map<String, String> saslProps, boolean assumeSubject) throws SaslException { try { String[] names = principal.split("[/@]"); if (names.length != 3) { throw new IllegalArgumentException("Kerberos principal should have 3 parts: " + principal); } if (assumeSubject) { return createSubjectAssumedTransport(principal, underlyingTransport, saslProps); } else { HadoopThriftAuthBridge.Client authBridge = ShimLoader.getHadoopThriftAuthBridge().createClientWithConf("kerberos"); return authBridge.createClientTransport(principal, host, "KERBEROS", null, underlyingTransport, saslProps); } } catch (IOException e) { throw new SaslException("Failed to open client transport", e); } } public static TTransport createSubjectAssumedTransport(String principal, TTransport underlyingTransport, Map<String, String> saslProps) throws IOException { String[] names = principal.split("[/@]"); try { TTransport saslTransport = new TSaslClientTransport("GSSAPI", null, names[0], names[1], saslProps, null, underlyingTransport); return new TSubjectAssumingTransport(saslTransport); } catch (SaslException se) { throw new IOException("Could not instantiate SASL transport", se); } } public static TTransport getTokenTransport(String tokenStr, String host, TTransport underlyingTransport, Map<String, String> saslProps) throws SaslException { HadoopThriftAuthBridge.Client authBridge = ShimLoader.getHadoopThriftAuthBridge().createClientWithConf("kerberos"); try { return authBridge.createClientTransport(null, host, "DIGEST", tokenStr, underlyingTransport, saslProps); } catch (IOException e) { throw new SaslException("Failed to open client transport", e); } } private KerberosSaslHelper() { throw new UnsupportedOperationException("Can't initialize class"); } private static class CLIServiceProcessorFactory extends TProcessorFactory { private final ThriftCLIService service; private final Server saslServer; public CLIServiceProcessorFactory(Server saslServer, ThriftCLIService service) { super(null); this.service = service; this.saslServer = saslServer; } @Override public TProcessor getProcessor(TTransport trans) { TProcessor sqlProcessor = new TCLIService.Processor<Iface>(service); return saslServer.wrapNonAssumingProcessor(sqlProcessor); } } }