HADOOP-6367. Removes Access Token implementation from common. Contributed by Kan Zhang.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@881509 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Devaraj Das 2009-11-17 20:59:46 +00:00
parent cdcb8514a0
commit bd92322d22
11 changed files with 3 additions and 855 deletions

View File

@ -653,6 +653,9 @@ Release 0.21.0 - Unreleased
HADOOP-6343. Log unexpected throwable object caught in RPC. (Jitendra Nath
Pandey via szetszwo)
HADOOP-6367. Removes Access Token implementation from common.
(Kan Zhang via ddas)
OPTIMIZATIONS
HADOOP-5595. NameNode does not need to run a replicator to choose a

View File

@ -269,29 +269,6 @@
<description>Disk usage statistics refresh interval in msec.</description>
</property>
<property>
<name>fs.access.token.enable</name>
<value>false</value>
<description>
If "true", access tokens are used as capabilities for accessing datanodes.
If "false", no access tokens are checked on accessing datanodes.
</description>
</property>
<property>
<name>fs.access.key.update.interval</name>
<value>600</value>
<description>
Interval in minutes at which namenode updates its access keys.
</description>
</property>
<property>
<name>fs.access.token.lifetime</name>
<value>600</value>
<description>The lifetime of access tokens in minutes.</description>
</property>
<property>
<name>fs.s3.block.size</name>
<value>67108864</value>

View File

@ -1757,12 +1757,6 @@ private static void addDeprecatedKeys() {
new String[]{CommonConfigurationKeys.FS_CLIENT_BUFFER_DIR_KEY});
Configuration.addDeprecation("hadoop.native.lib",
new String[]{CommonConfigurationKeys.IO_NATIVE_LIB_AVAILABLE_KEY});
Configuration.addDeprecation("dfs.access.token.enable",
new String[]{CommonConfigurationKeys.FS_ACCESS_TOKEN_ENABLE_KEY});
Configuration.addDeprecation("dfs.access.key.update.interval",
new String[]{CommonConfigurationKeys.FS_ACCESS_KEY_UPDATE_INTERVAL_KEY});
Configuration.addDeprecation("dfs.access.token.lifetime",
new String[]{CommonConfigurationKeys.FS_ACCESS_TOKEN_LIFETIME_KEY});
Configuration.addDeprecation("fs.default.name",
new String[]{CommonConfigurationKeys.FS_DEFAULT_NAME_KEY});
}

View File

@ -43,15 +43,6 @@ public class CommonConfigurationKeys {
public static final int FS_PERMISSIONS_UMASK_DEFAULT = 0022;
public static final String FS_DF_INTERVAL_KEY = "fs.df.interval";
public static final long FS_DF_INTERVAL_DEFAULT = 60000;
public static final String FS_ACCESS_TOKEN_ENABLE_KEY =
"fs.access.token.enable";
public static final boolean FS_ACCESS_TOKEN_ENABLE_DEFAULT = false;
public static final String FS_ACCESS_KEY_UPDATE_INTERVAL_KEY =
"fs.access.key.update.interval";
public static final long FS_ACCESS_KEY_UPDATE_INTERVAL_DEFAULT = 600;
public static final String FS_ACCESS_TOKEN_LIFETIME_KEY =
"fs.access.token.lifetime";
public static final long FS_ACCESS_TOKEN_LIFETIME_DEFAULT = 600;
//Defaults are not specified for following keys

View File

@ -1,110 +0,0 @@
/**
* 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.security;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import javax.crypto.Mac;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.io.WritableUtils;
/**
* Key used for generating and verifying access tokens
*/
public class AccessKey implements Writable {
private long keyID;
private Text key;
private long expiryDate;
private Mac mac;
public AccessKey() {
this(0L, new Text(), 0L);
}
public AccessKey(long keyID, Text key, long expiryDate) {
this.keyID = keyID;
this.key = key;
this.expiryDate = expiryDate;
}
public long getKeyID() {
return keyID;
}
public Text getKey() {
return key;
}
public long getExpiryDate() {
return expiryDate;
}
public Mac getMac() {
return mac;
}
public void setMac(Mac mac) {
this.mac = mac;
}
static boolean isEqual(Object a, Object b) {
return a == null ? b == null : a.equals(b);
}
/** {@inheritDoc} */
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof AccessKey) {
AccessKey that = (AccessKey) obj;
return this.keyID == that.keyID && isEqual(this.key, that.key)
&& this.expiryDate == that.expiryDate;
}
return false;
}
/** {@inheritDoc} */
public int hashCode() {
return key == null ? 0 : key.hashCode();
}
// ///////////////////////////////////////////////
// Writable
// ///////////////////////////////////////////////
/**
*/
public void write(DataOutput out) throws IOException {
WritableUtils.writeVLong(out, keyID);
key.write(out);
WritableUtils.writeVLong(out, expiryDate);
}
/**
*/
public void readFields(DataInput in) throws IOException {
keyID = WritableUtils.readVLong(in);
key.readFields(in);
expiryDate = WritableUtils.readVLong(in);
}
}

View File

@ -1,89 +0,0 @@
/**
* 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.security;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.Writable;
public class AccessToken implements Writable {
public static final AccessToken DUMMY_TOKEN = new AccessToken();
private Text tokenID;
private Text tokenAuthenticator;
public AccessToken() {
this(new Text(), new Text());
}
public AccessToken(Text tokenID, Text tokenAuthenticator) {
this.tokenID = tokenID;
this.tokenAuthenticator = tokenAuthenticator;
}
public Text getTokenID() {
return tokenID;
}
public Text getTokenAuthenticator() {
return tokenAuthenticator;
}
static boolean isEqual(Object a, Object b) {
return a == null ? b == null : a.equals(b);
}
/** {@inheritDoc} */
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof AccessToken) {
AccessToken that = (AccessToken) obj;
return isEqual(this.tokenID, that.tokenID)
&& isEqual(this.tokenAuthenticator, that.tokenAuthenticator);
}
return false;
}
/** {@inheritDoc} */
public int hashCode() {
return tokenAuthenticator == null ? 0 : tokenAuthenticator.hashCode();
}
// ///////////////////////////////////////////////
// Writable
// ///////////////////////////////////////////////
/**
*/
public void write(DataOutput out) throws IOException {
tokenID.write(out);
tokenAuthenticator.write(out);
}
/**
*/
public void readFields(DataInput in) throws IOException {
tokenID.readFields(in);
tokenAuthenticator.readFields(in);
}
}

View File

@ -1,312 +0,0 @@
/**
* 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.security;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.WritableUtils;
import org.apache.hadoop.fs.CommonConfigurationKeys;
/**
* AccessTokenHandler can be instantiated in 2 modes, master mode and slave
* mode. Master can generate new access keys and export access keys to slaves,
* while slaves can only import and use access keys received from master. Both
* master and slave can generate and verify access tokens. Typically, master
* mode is used by NN and slave mode is used by DN.
*/
public class AccessTokenHandler {
private static final Log LOG = LogFactory.getLog(AccessTokenHandler.class);
public static final String STRING_ENABLE_ACCESS_TOKEN =
CommonConfigurationKeys.FS_ACCESS_TOKEN_ENABLE_KEY;
public static final String STRING_ACCESS_KEY_UPDATE_INTERVAL =
CommonConfigurationKeys.FS_ACCESS_KEY_UPDATE_INTERVAL_KEY;
public static final String STRING_ACCESS_TOKEN_LIFETIME =
CommonConfigurationKeys.FS_ACCESS_TOKEN_LIFETIME_KEY;
private final boolean isMaster;
/*
* keyUpdateInterval is the interval that NN updates its access keys. It
* should be set long enough so that all live DN's and Balancer should have
* sync'ed their access keys with NN at least once during each interval.
*/
private final long keyUpdateInterval;
private long tokenLifetime;
private long serialNo = new SecureRandom().nextLong();
private KeyGenerator keyGen;
private AccessKey currentKey;
private AccessKey nextKey;
private Map<Long, AccessKey> allKeys;
public static enum AccessMode {
READ, WRITE, COPY, REPLACE
};
/**
* Constructor
*
* @param isMaster
* @param keyUpdateInterval
* @param tokenLifetime
* @throws IOException
*/
public AccessTokenHandler(boolean isMaster, long keyUpdateInterval,
long tokenLifetime) throws IOException {
this.isMaster = isMaster;
this.keyUpdateInterval = keyUpdateInterval;
this.tokenLifetime = tokenLifetime;
this.allKeys = new HashMap<Long, AccessKey>();
if (isMaster) {
try {
generateKeys();
initMac(currentKey);
} catch (GeneralSecurityException e) {
throw (IOException) new IOException(
"Failed to create AccessTokenHandler").initCause(e);
}
}
}
/** Initialize access keys */
private synchronized void generateKeys() throws NoSuchAlgorithmException {
keyGen = KeyGenerator.getInstance("HmacSHA1");
/*
* Need to set estimated expiry dates for currentKey and nextKey so that if
* NN crashes, DN can still expire those keys. NN will stop using the newly
* generated currentKey after the first keyUpdateInterval, however it may
* still be used by DN and Balancer to generate new tokens before they get a
* chance to sync their keys with NN. Since we require keyUpdInterval to be
* long enough so that all live DN's and Balancer will sync their keys with
* NN at least once during the period, the estimated expiry date for
* currentKey is set to now() + 2 * keyUpdateInterval + tokenLifetime.
* Similarly, the estimated expiry date for nextKey is one keyUpdateInterval
* more.
*/
serialNo++;
currentKey = new AccessKey(serialNo, new Text(keyGen.generateKey()
.getEncoded()), System.currentTimeMillis() + 2 * keyUpdateInterval
+ tokenLifetime);
serialNo++;
nextKey = new AccessKey(serialNo, new Text(keyGen.generateKey()
.getEncoded()), System.currentTimeMillis() + 3 * keyUpdateInterval
+ tokenLifetime);
allKeys.put(currentKey.getKeyID(), currentKey);
allKeys.put(nextKey.getKeyID(), nextKey);
}
/** Initialize Mac function */
private synchronized void initMac(AccessKey key) throws IOException {
try {
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(new SecretKeySpec(key.getKey().getBytes(), "HmacSHA1"));
key.setMac(mac);
} catch (GeneralSecurityException e) {
throw (IOException) new IOException(
"Failed to initialize Mac for access key, keyID=" + key.getKeyID())
.initCause(e);
}
}
/** Export access keys, only to be used in master mode */
public synchronized ExportedAccessKeys exportKeys() {
if (!isMaster)
return null;
if (LOG.isDebugEnabled())
LOG.debug("Exporting access keys");
return new ExportedAccessKeys(true, keyUpdateInterval, tokenLifetime,
currentKey, allKeys.values().toArray(new AccessKey[0]));
}
private synchronized void removeExpiredKeys() {
long now = System.currentTimeMillis();
for (Iterator<Map.Entry<Long, AccessKey>> it = allKeys.entrySet()
.iterator(); it.hasNext();) {
Map.Entry<Long, AccessKey> e = it.next();
if (e.getValue().getExpiryDate() < now) {
it.remove();
}
}
}
/**
* Set access keys, only to be used in slave mode
*/
public synchronized void setKeys(ExportedAccessKeys exportedKeys)
throws IOException {
if (isMaster || exportedKeys == null)
return;
LOG.info("Setting access keys");
removeExpiredKeys();
this.currentKey = exportedKeys.getCurrentKey();
initMac(currentKey);
AccessKey[] receivedKeys = exportedKeys.getAllKeys();
for (int i = 0; i < receivedKeys.length; i++) {
if (receivedKeys[i] == null)
continue;
this.allKeys.put(receivedKeys[i].getKeyID(), receivedKeys[i]);
}
}
/**
* Update access keys, only to be used in master mode
*/
public synchronized void updateKeys() throws IOException {
if (!isMaster)
return;
LOG.info("Updating access keys");
removeExpiredKeys();
// set final expiry date of retiring currentKey
allKeys.put(currentKey.getKeyID(), new AccessKey(currentKey.getKeyID(),
currentKey.getKey(), System.currentTimeMillis() + keyUpdateInterval
+ tokenLifetime));
// update the estimated expiry date of new currentKey
currentKey = new AccessKey(nextKey.getKeyID(), nextKey.getKey(), System
.currentTimeMillis()
+ 2 * keyUpdateInterval + tokenLifetime);
initMac(currentKey);
allKeys.put(currentKey.getKeyID(), currentKey);
// generate a new nextKey
serialNo++;
nextKey = new AccessKey(serialNo, new Text(keyGen.generateKey()
.getEncoded()), System.currentTimeMillis() + 3 * keyUpdateInterval
+ tokenLifetime);
allKeys.put(nextKey.getKeyID(), nextKey);
}
/** Check if token is well formed */
private synchronized boolean verifyToken(long keyID, AccessToken token)
throws IOException {
AccessKey key = allKeys.get(keyID);
if (key == null) {
LOG.warn("Access key for keyID=" + keyID + " doesn't exist.");
return false;
}
if (key.getMac() == null) {
initMac(key);
}
Text tokenID = token.getTokenID();
Text authenticator = new Text(key.getMac().doFinal(tokenID.getBytes()));
return authenticator.equals(token.getTokenAuthenticator());
}
/** Generate an access token for current user */
public AccessToken generateToken(long blockID, EnumSet<AccessMode> modes)
throws IOException {
UserGroupInformation ugi = UserGroupInformation.getCurrentUGI();
String userID = (ugi == null ? null : ugi.getUserName());
return generateToken(userID, blockID, modes);
}
/** Generate an access token for a specified user */
public synchronized AccessToken generateToken(String userID, long blockID,
EnumSet<AccessMode> modes) throws IOException {
if (LOG.isDebugEnabled()) {
LOG.debug("Generating access token for user=" + userID + ", blockID="
+ blockID + ", access modes=" + modes + ", keyID="
+ currentKey.getKeyID());
}
if (modes == null || modes.isEmpty())
throw new IOException("access modes can't be null or empty");
ByteArrayOutputStream buf = new ByteArrayOutputStream(4096);
DataOutputStream out = new DataOutputStream(buf);
WritableUtils.writeVLong(out, System.currentTimeMillis() + tokenLifetime);
WritableUtils.writeVLong(out, currentKey.getKeyID());
WritableUtils.writeString(out, userID);
WritableUtils.writeVLong(out, blockID);
WritableUtils.writeVInt(out, modes.size());
for (AccessMode aMode : modes) {
WritableUtils.writeEnum(out, aMode);
}
Text tokenID = new Text(buf.toByteArray());
return new AccessToken(tokenID, new Text(currentKey.getMac().doFinal(
tokenID.getBytes())));
}
/** Check if access should be allowed. userID is not checked if null */
public boolean checkAccess(AccessToken token, String userID, long blockID,
AccessMode mode) throws IOException {
long oExpiry = 0;
long oKeyID = 0;
String oUserID = null;
long oBlockID = 0;
EnumSet<AccessMode> oModes = EnumSet.noneOf(AccessMode.class);
try {
ByteArrayInputStream buf = new ByteArrayInputStream(token.getTokenID()
.getBytes());
DataInputStream in = new DataInputStream(buf);
oExpiry = WritableUtils.readVLong(in);
oKeyID = WritableUtils.readVLong(in);
oUserID = WritableUtils.readString(in);
oBlockID = WritableUtils.readVLong(in);
int length = WritableUtils.readVInt(in);
for (int i = 0; i < length; ++i) {
oModes.add(WritableUtils.readEnum(in, AccessMode.class));
}
} catch (IOException e) {
throw (IOException) new IOException(
"Unable to parse access token for user=" + userID + ", blockID="
+ blockID + ", access mode=" + mode).initCause(e);
}
if (LOG.isDebugEnabled()) {
LOG.debug("Verifying access token for user=" + userID + ", blockID="
+ blockID + ", access mode=" + mode + ", keyID=" + oKeyID);
}
return (userID == null || userID.equals(oUserID)) && oBlockID == blockID
&& !isExpired(oExpiry) && oModes.contains(mode)
&& verifyToken(oKeyID, token);
}
private static boolean isExpired(long expiryDate) {
return System.currentTimeMillis() > expiryDate;
}
/** check if a token is expired. for unit test only.
* return true when token is expired, false otherwise */
static boolean isTokenExpired(AccessToken token) throws IOException {
ByteArrayInputStream buf = new ByteArrayInputStream(token.getTokenID()
.getBytes());
DataInputStream in = new DataInputStream(buf);
long expiryDate = WritableUtils.readVLong(in);
return isExpired(expiryDate);
}
/** set token lifetime. for unit test only */
synchronized void setTokenLifetime(long tokenLifetime) {
this.tokenLifetime = tokenLifetime;
}
}

View File

@ -1,138 +0,0 @@
/**
* 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.security;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Arrays;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.io.WritableFactories;
import org.apache.hadoop.io.WritableFactory;
/**
* Object for passing access keys
*/
public class ExportedAccessKeys implements Writable {
public static final ExportedAccessKeys DUMMY_KEYS = new ExportedAccessKeys();
private boolean isAccessTokenEnabled;
private long keyUpdateInterval;
private long tokenLifetime;
private AccessKey currentKey;
private AccessKey[] allKeys;
public ExportedAccessKeys() {
this(false, 0, 0, new AccessKey(), new AccessKey[0]);
}
ExportedAccessKeys(boolean isAccessTokenEnabled, long keyUpdateInterval,
long tokenLifetime, AccessKey currentKey, AccessKey[] allKeys) {
this.isAccessTokenEnabled = isAccessTokenEnabled;
this.keyUpdateInterval = keyUpdateInterval;
this.tokenLifetime = tokenLifetime;
this.currentKey = currentKey;
this.allKeys = allKeys;
}
public boolean isAccessTokenEnabled() {
return isAccessTokenEnabled;
}
public long getKeyUpdateInterval() {
return keyUpdateInterval;
}
public long getTokenLifetime() {
return tokenLifetime;
}
public AccessKey getCurrentKey() {
return currentKey;
}
public AccessKey[] getAllKeys() {
return allKeys;
}
static boolean isEqual(Object a, Object b) {
return a == null ? b == null : a.equals(b);
}
/** {@inheritDoc} */
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof ExportedAccessKeys) {
ExportedAccessKeys that = (ExportedAccessKeys) obj;
return this.isAccessTokenEnabled == that.isAccessTokenEnabled
&& this.keyUpdateInterval == that.keyUpdateInterval
&& this.tokenLifetime == that.tokenLifetime
&& isEqual(this.currentKey, that.currentKey)
&& Arrays.equals(this.allKeys, that.allKeys);
}
return false;
}
/** {@inheritDoc} */
public int hashCode() {
return currentKey == null ? 0 : currentKey.hashCode();
}
// ///////////////////////////////////////////////
// Writable
// ///////////////////////////////////////////////
static { // register a ctor
WritableFactories.setFactory(ExportedAccessKeys.class,
new WritableFactory() {
public Writable newInstance() {
return new ExportedAccessKeys();
}
});
}
/**
*/
public void write(DataOutput out) throws IOException {
out.writeBoolean(isAccessTokenEnabled);
out.writeLong(keyUpdateInterval);
out.writeLong(tokenLifetime);
currentKey.write(out);
out.writeInt(allKeys.length);
for (int i = 0; i < allKeys.length; i++) {
allKeys[i].write(out);
}
}
/**
*/
public void readFields(DataInput in) throws IOException {
isAccessTokenEnabled = in.readBoolean();
keyUpdateInterval = in.readLong();
tokenLifetime = in.readLong();
currentKey.readFields(in);
this.allKeys = new AccessKey[in.readInt()];
for (int i = 0; i < allKeys.length; i++) {
allKeys[i] = new AccessKey();
allKeys[i].readFields(in);
}
}
}

View File

@ -1,36 +0,0 @@
/**
* 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.security;
import java.io.IOException;
/**
* Access token verification failed.
*/
public class InvalidAccessTokenException extends IOException {
private static final long serialVersionUID = 168L;
public InvalidAccessTokenException() {
super();
}
public InvalidAccessTokenException(String msg) {
super(msg);
}
}

View File

@ -1,43 +0,0 @@
/**
* 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.security;
import java.io.IOException;
/** Utilities for security tests */
public class SecurityTestUtil {
/**
* check if an access token is expired. return true when token is expired,
* false otherwise
*/
public static boolean isAccessTokenExpired(AccessToken token)
throws IOException {
return AccessTokenHandler.isTokenExpired(token);
}
/**
* set access token lifetime.
*/
public static void setAccessTokenLifetime(AccessTokenHandler handler,
long tokenLifetime) {
handler.setTokenLifetime(tokenLifetime);
}
}

View File

@ -1,89 +0,0 @@
/**
* 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.security;
import java.util.EnumSet;
import org.apache.hadoop.io.TestWritable;
import junit.framework.TestCase;
/** Unit tests for access tokens */
public class TestAccessToken extends TestCase {
long accessKeyUpdateInterval = 10 * 60 * 1000; // 10 mins
long accessTokenLifetime = 2 * 60 * 1000; // 2 mins
long blockID1 = 0L;
long blockID2 = 10L;
long blockID3 = -108L;
/** test Writable */
public void testWritable() throws Exception {
TestWritable.testWritable(ExportedAccessKeys.DUMMY_KEYS);
AccessTokenHandler handler = new AccessTokenHandler(true,
accessKeyUpdateInterval, accessTokenLifetime);
ExportedAccessKeys keys = handler.exportKeys();
TestWritable.testWritable(keys);
TestWritable.testWritable(AccessToken.DUMMY_TOKEN);
AccessToken token = handler.generateToken(blockID3, EnumSet
.allOf(AccessTokenHandler.AccessMode.class));
TestWritable.testWritable(token);
}
private void tokenGenerationAndVerification(AccessTokenHandler master,
AccessTokenHandler slave) throws Exception {
// single-mode tokens
for (AccessTokenHandler.AccessMode mode : AccessTokenHandler.AccessMode
.values()) {
// generated by master
AccessToken token1 = master.generateToken(blockID1, EnumSet.of(mode));
assertTrue(master.checkAccess(token1, null, blockID1, mode));
assertTrue(slave.checkAccess(token1, null, blockID1, mode));
// generated by slave
AccessToken token2 = slave.generateToken(blockID2, EnumSet.of(mode));
assertTrue(master.checkAccess(token2, null, blockID2, mode));
assertTrue(slave.checkAccess(token2, null, blockID2, mode));
}
// multi-mode tokens
AccessToken mtoken = master.generateToken(blockID3, EnumSet
.allOf(AccessTokenHandler.AccessMode.class));
for (AccessTokenHandler.AccessMode mode : AccessTokenHandler.AccessMode
.values()) {
assertTrue(master.checkAccess(mtoken, null, blockID3, mode));
assertTrue(slave.checkAccess(mtoken, null, blockID3, mode));
}
}
/** test access key and token handling */
public void testAccessTokenHandler() throws Exception {
AccessTokenHandler masterHandler = new AccessTokenHandler(true,
accessKeyUpdateInterval, accessTokenLifetime);
AccessTokenHandler slaveHandler = new AccessTokenHandler(false,
accessKeyUpdateInterval, accessTokenLifetime);
ExportedAccessKeys keys = masterHandler.exportKeys();
slaveHandler.setKeys(keys);
tokenGenerationAndVerification(masterHandler, slaveHandler);
// key updating
masterHandler.updateKeys();
tokenGenerationAndVerification(masterHandler, slaveHandler);
keys = masterHandler.exportKeys();
slaveHandler.setKeys(keys);
tokenGenerationAndVerification(masterHandler, slaveHandler);
}
}