/// <summary> /// This method is intended to be used for recovering persisted delegation /// tokens /// This method must be called before this secret manager is activated (before /// startThreads() is called) /// </summary> /// <param name="identifier">identifier read from persistent storage</param> /// <param name="renewDate">token renew time</param> /// <exception cref="System.IO.IOException"/> public virtual void AddPersistedDelegationToken(TokenIdent identifier, long renewDate ) { lock (this) { if (running) { // a safety check throw new IOException("Can't add persisted delegation token to a running SecretManager." ); } int keyId = identifier.GetMasterKeyId(); DelegationKey dKey = allKeys[keyId]; if (dKey == null) { Log.Warn("No KEY found for persisted identifier " + identifier.ToString()); return; } byte[] password = CreatePassword(identifier.GetBytes(), dKey.GetKey()); if (identifier.GetSequenceNumber() > GetDelegationTokenSeqNum()) { SetDelegationTokenSeqNum(identifier.GetSequenceNumber()); } if (GetTokenInfo(identifier) == null) { currentTokens[identifier] = new AbstractDelegationTokenSecretManager.DelegationTokenInformation (renewDate, password, GetTrackingIdIfEnabled(identifier)); } else { throw new IOException("Same delegation token being added twice."); } } }
/// <summary>Cancel a token by removing it from cache.</summary> /// <returns>Identifier of the canceled token</returns> /// <exception cref="Org.Apache.Hadoop.Security.Token.SecretManager.InvalidToken">for invalid token /// </exception> /// <exception cref="Org.Apache.Hadoop.Security.AccessControlException">if the user isn't allowed to cancel /// </exception> /// <exception cref="System.IO.IOException"/> public virtual TokenIdent CancelToken(Org.Apache.Hadoop.Security.Token.Token <TokenIdent > token, string canceller) { lock (this) { ByteArrayInputStream buf = new ByteArrayInputStream(token.GetIdentifier()); DataInputStream @in = new DataInputStream(buf); TokenIdent id = CreateIdentifier(); id.ReadFields(@in); Log.Info("Token cancelation requested for identifier: " + id); if (id.GetUser() == null) { throw new SecretManager.InvalidToken("Token with no owner"); } string owner = id.GetUser().GetUserName(); Text renewer = id.GetRenewer(); HadoopKerberosName cancelerKrbName = new HadoopKerberosName(canceller); string cancelerShortName = cancelerKrbName.GetShortName(); if (!canceller.Equals(owner) && (renewer == null || renewer.ToString().IsEmpty() || !cancelerShortName.Equals(renewer.ToString()))) { throw new AccessControlException(canceller + " is not authorized to cancel the token" ); } AbstractDelegationTokenSecretManager.DelegationTokenInformation info = Collections.Remove (currentTokens, id); if (info == null) { throw new SecretManager.InvalidToken("Token not found"); } RemoveStoredToken(id); return(id); } }
protected internal override byte[] CreatePassword(TokenIdent identifier) { lock (this) { int sequenceNum; long now = Time.Now(); sequenceNum = IncrementDelegationTokenSeqNum(); identifier.SetIssueDate(now); identifier.SetMaxDate(now + tokenMaxLifetime); identifier.SetMasterKeyId(currentKey.GetKeyId()); identifier.SetSequenceNumber(sequenceNum); Log.Info("Creating password for identifier: " + identifier + ", currentKey: " + currentKey .GetKeyId()); byte[] password = CreatePassword(identifier.GetBytes(), currentKey.GetKey()); AbstractDelegationTokenSecretManager.DelegationTokenInformation tokenInfo = new AbstractDelegationTokenSecretManager.DelegationTokenInformation (now + tokenRenewInterval, password, GetTrackingIdIfEnabled(identifier)); try { StoreToken(identifier, tokenInfo); } catch (IOException ioe) { Log.Error("Could not store token !!", ioe); } return(password); } }
/// <exception cref="System.IO.IOException"/> private void ProcessTokenAddOrUpdate(ChildData data) { ByteArrayInputStream bin = new ByteArrayInputStream(data.GetData()); DataInputStream din = new DataInputStream(bin); TokenIdent ident = CreateIdentifier(); ident.ReadFields(din); long renewDate = din.ReadLong(); int pwdLen = din.ReadInt(); byte[] password = new byte[pwdLen]; int numRead = din.Read(password, 0, pwdLen); if (numRead > -1) { AbstractDelegationTokenSecretManager.DelegationTokenInformation tokenInfo = new AbstractDelegationTokenSecretManager.DelegationTokenInformation (renewDate, password); lock (this) { currentTokens[ident] = tokenInfo; // The cancel task might be waiting Runtime.NotifyAll(this); } } }
/// <exception cref="System.Exception"/> private void AddOrUpdateToken(TokenIdent ident, AbstractDelegationTokenSecretManager.DelegationTokenInformation info, bool isUpdate) { string nodeCreatePath = GetNodePath(ZkDtsmTokensRoot, DelegationTokenPrefix + ident .GetSequenceNumber()); ByteArrayOutputStream tokenOs = new ByteArrayOutputStream(); DataOutputStream tokenOut = new DataOutputStream(tokenOs); ByteArrayOutputStream seqOs = new ByteArrayOutputStream(); try { ident.Write(tokenOut); tokenOut.WriteLong(info.GetRenewDate()); tokenOut.WriteInt(info.GetPassword().Length); tokenOut.Write(info.GetPassword()); if (Log.IsDebugEnabled()) { Log.Debug((isUpdate ? "Updating " : "Storing ") + "ZKDTSMDelegationToken_" + ident .GetSequenceNumber()); } if (isUpdate) { zkClient.SetData().ForPath(nodeCreatePath, tokenOs.ToByteArray()).SetVersion(-1); } else { zkClient.Create().WithMode(CreateMode.Persistent).ForPath(nodeCreatePath, tokenOs .ToByteArray()); } } finally { seqOs.Close(); } }
/// <exception cref="System.IO.IOException"/> protected internal override void StoreToken(TokenIdent ident, AbstractDelegationTokenSecretManager.DelegationTokenInformation tokenInfo) { try { AddOrUpdateToken(ident, tokenInfo, false); } catch (Exception e) { throw new RuntimeException(e); } }
/// <summary>Renew a delegation token.</summary> /// <param name="token">the token to renew</param> /// <param name="renewer">the full principal name of the user doing the renewal</param> /// <returns>the new expiration time</returns> /// <exception cref="Org.Apache.Hadoop.Security.Token.SecretManager.InvalidToken">if the token is invalid /// </exception> /// <exception cref="Org.Apache.Hadoop.Security.AccessControlException">if the user can't renew token /// </exception> /// <exception cref="System.IO.IOException"/> public virtual long RenewToken(Org.Apache.Hadoop.Security.Token.Token <TokenIdent> token, string renewer) { lock (this) { ByteArrayInputStream buf = new ByteArrayInputStream(token.GetIdentifier()); DataInputStream @in = new DataInputStream(buf); TokenIdent id = CreateIdentifier(); id.ReadFields(@in); Log.Info("Token renewal for identifier: " + id + "; total currentTokens " + currentTokens .Count); long now = Time.Now(); if (id.GetMaxDate() < now) { throw new SecretManager.InvalidToken(renewer + " tried to renew an expired token" ); } if ((id.GetRenewer() == null) || (id.GetRenewer().ToString().IsEmpty())) { throw new AccessControlException(renewer + " tried to renew a token without a renewer" ); } if (!id.GetRenewer().ToString().Equals(renewer)) { throw new AccessControlException(renewer + " tries to renew a token with renewer " + id.GetRenewer()); } DelegationKey key = GetDelegationKey(id.GetMasterKeyId()); if (key == null) { throw new SecretManager.InvalidToken("Unable to find master key for keyId=" + id. GetMasterKeyId() + " from cache. Failed to renew an unexpired token" + " with sequenceNumber=" + id.GetSequenceNumber()); } byte[] password = CreatePassword(token.GetIdentifier(), key.GetKey()); if (!Arrays.Equals(password, token.GetPassword())) { throw new AccessControlException(renewer + " is trying to renew a token with wrong password" ); } long renewTime = Math.Min(id.GetMaxDate(), now + tokenRenewInterval); string trackingId = GetTrackingIdIfEnabled(id); AbstractDelegationTokenSecretManager.DelegationTokenInformation info = new AbstractDelegationTokenSecretManager.DelegationTokenInformation (renewTime, password, trackingId); if (GetTokenInfo(id) == null) { throw new SecretManager.InvalidToken("Renewal request for unknown token"); } UpdateToken(id, info); return(renewTime); } }
public virtual string GetTokenTrackingId(TokenIdent identifier) { lock (this) { AbstractDelegationTokenSecretManager.DelegationTokenInformation info = GetTokenInfo (identifier); if (info == null) { return(null); } return(info.GetTrackingId()); } }
CheckToken(TokenIdent identifier) { System.Diagnostics.Debug.Assert(Thread.HoldsLock(this)); AbstractDelegationTokenSecretManager.DelegationTokenInformation info = GetTokenInfo (identifier); if (info == null) { throw new SecretManager.InvalidToken("token (" + identifier.ToString() + ") can't be found in cache" ); } if (info.GetRenewDate() < Time.Now()) { throw new SecretManager.InvalidToken("token (" + identifier.ToString() + ") is expired" ); } return(info); }
public virtual void TestParallelDelegationTokenCreation() { TestDelegationToken.TestDelegationTokenSecretManager dtSecretManager = new TestDelegationToken.TestDelegationTokenSecretManager (2000, 24 * 60 * 60 * 1000, 7 * 24 * 60 * 60 * 1000, 2000); try { dtSecretManager.StartThreads(); int numThreads = 100; int numTokensPerThread = 100; Thread[] issuers = new Thread[numThreads]; for (int i = 0; i < numThreads; i++) { issuers[i] = new Daemon(new _T1720540651(this)); issuers[i].Start(); } for (int i_1 = 0; i_1 < numThreads; i_1++) { issuers[i_1].Join(); } IDictionary <TestDelegationToken.TestDelegationTokenIdentifier, AbstractDelegationTokenSecretManager.DelegationTokenInformation > tokenCache = dtSecretManager.GetAllTokens(); Assert.Equal(numTokensPerThread * numThreads, tokenCache.Count ); IEnumerator <TestDelegationToken.TestDelegationTokenIdentifier> iter = tokenCache. Keys.GetEnumerator(); while (iter.HasNext()) { TestDelegationToken.TestDelegationTokenIdentifier id = iter.Next(); AbstractDelegationTokenSecretManager.DelegationTokenInformation info = tokenCache [id]; Assert.True(info != null); DelegationKey key = dtSecretManager.GetKey(id); Assert.True(key != null); byte[] storedPassword = dtSecretManager.RetrievePassword(id); byte[] password = dtSecretManager.CreatePassword(id, key); Assert.True(Arrays.Equals(password, storedPassword)); //verify by secret manager api dtSecretManager.VerifyToken(id, password); } } finally { dtSecretManager.StopThreads(); } }
/// <exception cref="System.IO.IOException"/> private AbstractDelegationTokenSecretManager.DelegationTokenInformation GetTokenInfoFromZK (TokenIdent ident, bool quiet) { string nodePath = GetNodePath(ZkDtsmTokensRoot, DelegationTokenPrefix + ident.GetSequenceNumber ()); try { byte[] data = zkClient.GetData().ForPath(nodePath); if ((data == null) || (data.Length == 0)) { return(null); } ByteArrayInputStream bin = new ByteArrayInputStream(data); DataInputStream din = new DataInputStream(bin); CreateIdentifier().ReadFields(din); long renewDate = din.ReadLong(); int pwdLen = din.ReadInt(); byte[] password = new byte[pwdLen]; int numRead = din.Read(password, 0, pwdLen); if (numRead > -1) { AbstractDelegationTokenSecretManager.DelegationTokenInformation tokenInfo = new AbstractDelegationTokenSecretManager.DelegationTokenInformation (renewDate, password); return(tokenInfo); } } catch (KeeperException.NoNodeException) { if (!quiet) { Log.Error("No node in path [" + nodePath + "]"); } } catch (Exception ex) { throw new IOException(ex); } return(null); }
/// <exception cref="System.IO.IOException"/> protected internal override void UpdateToken(TokenIdent ident, AbstractDelegationTokenSecretManager.DelegationTokenInformation tokenInfo) { string nodeRemovePath = GetNodePath(ZkDtsmTokensRoot, DelegationTokenPrefix + ident .GetSequenceNumber()); try { if (zkClient.CheckExists().ForPath(nodeRemovePath) != null) { AddOrUpdateToken(ident, tokenInfo, true); } else { AddOrUpdateToken(ident, tokenInfo, false); Log.Debug("Attempted to update a non-existing znode " + nodeRemovePath); } } catch (Exception e) { throw new RuntimeException("Could not update Stored Token ZKDTSMDelegationToken_" + ident.GetSequenceNumber(), e); } }
GetTokenInfo(TokenIdent ident) { // First check if I have this.. AbstractDelegationTokenSecretManager.DelegationTokenInformation tokenInfo = currentTokens [ident]; // Then query ZK if (tokenInfo == null) { try { tokenInfo = GetTokenInfoFromZK(ident); if (tokenInfo != null) { currentTokens[ident] = tokenInfo; } } catch (IOException e) { Log.Error("Error retrieving tokenInfo [" + ident.GetSequenceNumber() + "] from ZK" , e); } } return(tokenInfo); }
/// <summary> /// For subclasses externalizing the storage, for example Zookeeper /// based implementations /// </summary> /// <exception cref="System.IO.IOException"/> protected internal virtual void UpdateToken(TokenIdent ident, AbstractDelegationTokenSecretManager.DelegationTokenInformation tokenInfo) { currentTokens[ident] = tokenInfo; UpdateStoredToken(ident, tokenInfo.GetRenewDate()); }