Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * 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.hadoop.hbase.security.token;
 
 import java.util.Map;
 
Manages an internal list of secret keys used to sign new authentication tokens as they are generated, and to valid existing tokens used for authentication.

A single instance of AuthenticationTokenSecretManager will be running as the "leader" in a given HBase cluster. The leader is responsible for periodically generating new secret keys, which are then distributed to followers via ZooKeeper, and for expiring previously used secret keys that are no longer needed (as any tokens using them have expired).

 
 
   static final String NAME_PREFIX = "SecretManager-";
 
   private static Log LOG = LogFactory.getLog(
 
   private long lastKeyUpdate;
   private long keyUpdateInterval;
   private long tokenMaxLifetime;
   private ZKSecretWatcher zkWatcher;
   private ZKClusterId clusterId;
 
 
   private int idSeq;
   private AtomicLong tokenSeq = new AtomicLong();
   private String name;

  
Create a new secret manager instance for generating keys.

Parameters:
conf Configuration to use
zk Connection to zookeeper for handling leader elections
keyUpdateInterval Time (in milliseconds) between rolling a new master key for token signing
tokenMaxLifetime Maximum age (in milliseconds) before a token expires and is no longer valid
 
   /* TODO: Restrict access to this constructor to make rogues instances more difficult.
    * For the moment this class is instantiated from
    * org.apache.hadoop.hbase.ipc.SecureServer so public access is needed.
    */
       ZooKeeperWatcher zkString serverName,
       long keyUpdateIntervallong tokenMaxLifetime) {
     this. = new ZKSecretWatcher(confzkthis);
     this. = keyUpdateInterval;
     this. = tokenMaxLifetime;
     this. = new LeaderElector(zkserverName);
    this. = +serverName;
    this. = new ZKClusterId(zkzk);
  }
  public void start() {
    try {
      // populate any existing keys
      this..start();
      // try to become leader
      this..start();
    } catch (KeeperException ke) {
      .error("Zookeeper initialization failed"ke);
    }
  }
  public void stop() {
    this..stop("SecretManager stopping");
  }
  public boolean isMaster() {
    return .isMaster();
  }
  public String getName() {
    return ;
  }
  protected byte[] createPassword(AuthenticationTokenIdentifier identifier) {
    long now = EnvironmentEdgeManager.currentTimeMillis();
    AuthenticationKey secretKey = ;
    identifier.setKeyId(secretKey.getKeyId());
    identifier.setIssueDate(now);
    identifier.setExpirationDate(now + );
    return createPassword(identifier.getBytes(),
        secretKey.getKey());
  }
  public byte[] retrievePassword(AuthenticationTokenIdentifier identifier)
      throws InvalidToken {
    long now = EnvironmentEdgeManager.currentTimeMillis();
    if (identifier.getExpirationDate() < now) {
      throw new InvalidToken("Token has expired");
    }
    AuthenticationKey masterKey = .get(identifier.getKeyId());
    if (masterKey == null) {
      throw new InvalidToken("Unknown master key for token (id="+
          identifier.getKeyId()+")");
    }
    // regenerate the password
    return createPassword(identifier.getBytes(),
        masterKey.getKey());
  }
    return new AuthenticationTokenIdentifier();
  }
        new AuthenticationTokenIdentifier(username);
        new Token<AuthenticationTokenIdentifier>(identthis);
    if (.hasId()) {
      token.setService(new Text(.getId()));
    }
    return token;
  }
  public synchronized void addKey(AuthenticationKey keythrows IOException {
    // ignore zk changes when running as master
    if (.isMaster()) {
      if (.isDebugEnabled()) {
        .debug("Running as master, ignoring new key "+key.getKeyId());
      }
      return;
    }
    if (.isDebugEnabled()) {
      .debug("Adding key "+key.getKeyId());
    }
    .put(key.getKeyId(), key);
    if ( == null || key.getKeyId() > .getKeyId()) {
       = key;
    }
    // update current sequence
    if (key.getKeyId() > ) {
       = key.getKeyId();
    }
  }
  synchronized boolean removeKey(Integer keyId) {
    // ignore zk changes when running as master
    if (.isMaster()) {
      if (.isDebugEnabled()) {
        .debug("Running as master, ignoring removed key "+keyId);
      }
      return false;
    }
    if (.isDebugEnabled()) {
      .debug("Removing key "+keyId);
    }
    .remove(keyId);
    return true;
  }
    return ;
  }
  AuthenticationKey getKey(int keyId) {
    return .get(keyId);
  }
  synchronized void removeExpiredKeys() {
    if (!.isMaster()) {
      .info("Skipping removeExpiredKeys() because not running as master.");
      return;
    }
    long now = EnvironmentEdgeManager.currentTimeMillis();
    while (iter.hasNext()) {
      AuthenticationKey key = iter.next();
      if (key.getExpiration() < now) {
        if (.isDebugEnabled()) {
          .debug("Removing expired key "+key.getKeyId());
        }
        iter.remove();
        .removeKeyFromZK(key);
      }
    }
  }
  
  synchronized boolean isCurrentKeyRolled() {
    return  != null;
  }
  synchronized void rollCurrentKey() {
    if (!.isMaster()) {
      .info("Skipping rollCurrentKey() because not running as master.");
      return;
    }
    long now = EnvironmentEdgeManager.currentTimeMillis();
    AuthenticationKey prev = ;
    AuthenticationKey newKey = new AuthenticationKey(++,
        .// don't allow to expire until it's replaced by a new key
        generateSecret());
    .put(newKey.getKeyId(), newKey);
     = newKey;
    .addKeyToZK(newKey);
     = now;
    if (prev != null) {
      // make sure previous key is still stored
      prev.setExpiration(now + );
      .put(prev.getKeyId(), prev);
      .updateKeyInZK(prev);
    }
  }
  public static SecretKey createSecretKey(byte[] raw) {
    return SecretManager.createSecretKey(raw);
  }
  private class LeaderElector extends Thread implements Stoppable {
    private boolean stopped = false;
    
Flag indicating whether we're in charge of rolling/expiring keys
    private boolean isMaster = false;
    private ZKLeaderManager zkLeader;
    public LeaderElector(ZooKeeperWatcher watcherString serverName) {
      setDaemon(true);
      setName("ZKSecretWatcher-leaderElector");
       = new ZKLeaderManager(watcher,
          ZKUtil.joinZNode(.getRootKeyZNode(), "keymaster"),
          Bytes.toBytes(serverName), this);
    }
    public boolean isMaster() {
      return ;
    }
    @Override
    public boolean isStopped() {
      return ;
    }
    @Override
    public void stop(String reason) {
      if () {
        return;
      }
       = true;
      // prevent further key generation when stopping
      if () {
        .stepDownAsLeader();
      }
       = false;
      .info("Stopping leader election, because: "+reason);
      interrupt();
    }
    public void run() {
      .start();
       = true;
      while (!) {
        long now = EnvironmentEdgeManager.currentTimeMillis();
        // clear any expired
        removeExpiredKeys();
        if ( +  < now) {
          // roll a new master key
          rollCurrentKey();
        }
        try {
          Thread.sleep(5000);
        } catch (InterruptedException ie) {
          if (.isDebugEnabled()) {
            .debug("Interrupted waiting for next update"ie);
          }
        }
      }
    }
  }
New to GrepCode? Check out our FAQ X