internal virtual string GetServerPrincipal(RpcHeaderProtos.RpcSaslProto.SaslAuth authType) { KerberosInfo krbInfo = SecurityUtil.GetKerberosInfo(protocol, conf); Log.Debug("Get kerberos info proto:" + protocol + " info:" + krbInfo); if (krbInfo == null) { // protocol has no support for kerberos return(null); } string serverKey = krbInfo.ServerPrincipal(); if (serverKey == null) { throw new ArgumentException("Can't obtain server Kerberos config key from protocol=" + protocol.GetCanonicalName()); } // construct server advertised principal for comparision string serverPrincipal = new KerberosPrincipal(authType.GetProtocol() + "/" + authType .GetServerId(), KerberosPrincipal.KrbNtSrvHst).GetName(); bool isPrincipalValid = false; // use the pattern if defined string serverKeyPattern = conf.Get(serverKey + ".pattern"); if (serverKeyPattern != null && !serverKeyPattern.IsEmpty()) { Pattern pattern = GlobPattern.Compile(serverKeyPattern); isPrincipalValid = pattern.Matcher(serverPrincipal).Matches(); } else { // check that the server advertised principal matches our conf string confPrincipal = SecurityUtil.GetServerPrincipal(conf.Get(serverKey), serverAddr .Address); if (Log.IsDebugEnabled()) { Log.Debug("getting serverKey: " + serverKey + " conf value: " + conf.Get(serverKey ) + " principal: " + confPrincipal); } if (confPrincipal == null || confPrincipal.IsEmpty()) { throw new ArgumentException("Failed to specify server's Kerberos principal name"); } KerberosName name = new KerberosName(confPrincipal); if (name.GetHostName() == null) { throw new ArgumentException("Kerberos principal name does NOT have the expected hostname part: " + confPrincipal); } isPrincipalValid = serverPrincipal.Equals(confPrincipal); } if (!isPrincipalValid) { throw new ArgumentException("Server has invalid Kerberos principal: " + serverPrincipal ); } return(serverPrincipal); }
/// <summary>Try to create a SaslClient for an authentication type.</summary> /// <remarks> /// Try to create a SaslClient for an authentication type. May return /// null if the type isn't supported or the client lacks the required /// credentials. /// </remarks> /// <param name="authType">- the requested authentication method</param> /// <returns>SaslClient for the authType or null</returns> /// <exception cref="Javax.Security.Sasl.SaslException">- error instantiating client</exception> /// <exception cref="System.IO.IOException">- misc errors</exception> private SaslClient CreateSaslClient(RpcHeaderProtos.RpcSaslProto.SaslAuth authType ) { string saslUser = null; // SASL requires the client and server to use the same proto and serverId // if necessary, auth types below will verify they are valid string saslProtocol = authType.GetProtocol(); string saslServerName = authType.GetServerId(); IDictionary <string, string> saslProperties = saslPropsResolver.GetClientProperties (serverAddr.Address); CallbackHandler saslCallback = null; SaslRpcServer.AuthMethod method = SaslRpcServer.AuthMethod.ValueOf(authType.GetMethod ()); switch (method) { case SaslRpcServer.AuthMethod.Token: { Org.Apache.Hadoop.Security.Token.Token <object> token = GetServerToken(authType); if (token == null) { return(null); } // tokens aren't supported or user doesn't have one saslCallback = new SaslRpcClient.SaslClientCallbackHandler(token); break; } case SaslRpcServer.AuthMethod.Kerberos: { if (ugi.GetRealAuthenticationMethod().GetAuthMethod() != SaslRpcServer.AuthMethod .Kerberos) { return(null); } // client isn't using kerberos string serverPrincipal = GetServerPrincipal(authType); if (serverPrincipal == null) { return(null); } // protocol doesn't use kerberos if (Log.IsDebugEnabled()) { Log.Debug("RPC Server's Kerberos principal name for protocol=" + protocol.GetCanonicalName () + " is " + serverPrincipal); } break; } default: { throw new IOException("Unknown authentication method " + method); } } string mechanism = method.GetMechanismName(); if (Log.IsDebugEnabled()) { Log.Debug("Creating SASL " + mechanism + "(" + method + ") " + " client to authenticate to service at " + saslServerName); } return(Javax.Security.Sasl.Sasl.CreateSaslClient(new string[] { mechanism }, saslUser , saslProtocol, saslServerName, saslProperties, saslCallback)); }