src.com.ibm.as400.security.auth.ProfileTokenCredential Maven / Gradle / Ivy
Show all versions of jt400-jdk8 Show documentation
////////////////////////////////////////////////////////////////////////////////
//
// JTOpen (IBM Toolbox for Java - OSS version)
//
// Filename: ProfileTokenCredential.java
//
// The source code contained herein is licensed under the IBM Public License
// Version 1.0, which has been approved by the Open Source Initiative.
// Copyright (C) 1997-2003 International Business Machines Corporation and
// others. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
package com.ibm.as400.security.auth;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.AS400SecurityException;
import com.ibm.as400.access.ExtendedIllegalArgumentException;
import com.ibm.as400.access.ExtendedIllegalStateException;
import com.ibm.as400.access.Trace;
import java.beans.PropertyVetoException;
import java.util.Random;
/**
* The ProfileTokenCredential class represents an IBM i system profile token.
*
* A profile token provides a timed credential representing an
* authenticated system user profile and password. A profile token can be
* established in either a remote (not running on the target system) or local
* (running on the target system) context. Once created, it may be
* serialized or distributed as required by the application.
*
*
When referenced from a running process on the associated IBM i system,
* a profile token can be used to modify or swap the thread
* identity and perform a specific task or tasks on behalf of the
* authenticated user. However, a profile token generated on one IBM i
* system cannot be used to swap thread identity on any other system.
*
*
An application of this support would be in a single tier
* application running on the system when a designated operation must be
* run under the system authorities and permissions of a specific
* user profile. A profile token can be used to swap identity prior
* to performing the operation. Support is also provided to swap
* back to the original identity upon completion.
*
*
Another application of this support might be in a two tier
* application, with authentication of a user profile and password being
* performed by a graphical user interface on the first tier (i.e. a PC) and
* work being performed for that user on the second tier (the IBM i system).
* By utilizing ProfileTokenCredentials, the application can avoid directly
* passing the user ID and password over the network. The profile token can
* be distributed as required to the program on the second tier, which can
* perform the swap() and run designated operations under the
* system authorities and permissions assigned to the user.
*
*
Note: While inherently more secure than passing a user profile
* and password due to limited life span, profile tokens should still be
* considered sensitive information by the application and handled accordingly.
* Since the token represents an authenticated user and password, it could
* potentially be exploited by a hostile application to perform work on
* behalf of that user. It is ultimately the responsibility of the
* application to ensure that credentials are accessed in a secure manner.
*
*
Profile tokens are only supported for IBM i systems
* at release V4R5M0 or greater.
*
*
The following example demonstrates the use of a ProfileTokenCredential
* when run on the local IBM i system. (Note: swap() is an
* unsupported remote operation.)
*
*
* // Prepare to work with the local IBM i system.
* AS400 system = new AS400("localhost", "*CURRENT", "*CURRENT");
*
* // Create a single-use ProfileTokenCredential with a 60 second timeout.
* // A valid user ID and password must be substituted.
* ProfileTokenCredential pt = new ProfileTokenCredential();
* pt.setSystem(system);
* pt.setTimeoutInterval(60);
* pt.setTokenType(ProfileTokenCredential.TYPE_SINGLE_USE);
* pt.setTokenExtended("USERID", "PASSWORD");
*
* // Swap the thread identity, retrieving a credential to
* // later swap back to the original identity.
* AS400Credential cr = pt.swap(true);
*
* // Perform work under the swapped identity at this point.
* // Newly-connected AS400 objects will run under the new (swapped-to) identity.
* AS400 swapped = new AS400("localhost", "*CURRENT", "*CURRENT");
*
* // Swap back to the original thread identity.
* cr.swap();
*
* // Clean up the credentials.
* cr.destroy();
* pt.destroy();
*
*
* General restrictions:
*
* - Creating a token updates the last-used date for the associated
* user and group profiles.
* - Creating a token resets the 'signon attempts not valid' count to
* zero for the user profile.
* - If security-related events are being audited, creating a token
* adds an entry to the AUDJRN audit journal.
* - The maximum number of profile tokens that can be generated is
* approximately 2,000,000; after that, the space to store them is full.
* Message CPF4AAA is sent to the caller, and no more profile
* tokens can be generated until one is removed.
* - You cannot obtain a profile token for the following
* system-supplied user profiles:
*
* - QAUTPROF
*
- QFNC
*
- QNETSPLF
*
- QSPLJOB
*
- QDBSHR
*
- QGATE
*
- QNFSANON
*
- QSYS
*
- QDFTOWN
*
- QLPAUTO
*
- QRJE
*
- QTCP
*
- QDIRSRV
*
- QLPINSTALL
*
- QSNADS
*
- QTFTP
*
- QDOC
*
- QMSF
*
- QSPL
*
- QTSTRQS
*
- QDSNX
*
*
*
*
* Guidelines and restrictions for generating profile tokens based
* on a specified user profile name and password:
*
* - On level 10 systems, only the user ID is validated
* because no passwords are required.
* - If a provided password is not correct, the incorrect password
* count for the user profile is increased. (The QMAXSIGN system
* value contains the maximum number of incorrect attempts to sign on.)
* - If the QMAXSGNACN system value is set to disable
* user profiles, repeated attempts to validate an incorrect
* password disables the user ID. This keeps applications
* from methodically determining user passwords.
* - Considerations when specifying a password of *NOPWD or *NOPWDCHK:
*
* - To obtain a profile token for a profile that does not have a
* password, specify *NOPWD or *NOPWDCHK for the password
* parameter.
* - The user requesting the profile token must have *USE
* authority to the user profile.
* - *NOPWD is not allowed if the user profile name is the name
* of the currently running user profile.
* - If the password is *NOPWDCHK and the user requesting the
* profile token has *ALLOBJ and *SECADM special authorities, a
* profile token will be generated even when the status of the
* profile is disabled or its password is expired.
* - No profile token is created in the following situations:
*
* - The user profile is disabled and *NOPWDCHK is not
* specified for the password parameter, or *NOPWDCHK was
* specified but the user requesting the profile token does
* not have *ALLOBJ or *SECADM special authority.
* - The password is expired and *NOPWDCHK is not
* specified for the password parameter, or *NOPWDCHK was
* specified but the user requesting the profile token does
* not have *ALLOBJ or *SECADM special authority.
* - The password is *NONE, and *NOPWD or *NOPWDCHK is not
* specified for the password parameter.
*
*
*
*
*
*
* @see AS400Credential
*
*/
public final class ProfileTokenCredential extends AS400Credential
implements AS400BasicAuthenticationCredential {
static final long serialVersionUID = 4L;
private byte[] addr_ = new byte[9]; // Encode/decode adder
private byte[] mask_ = new byte[7]; // Encode/decode mask
private byte[] token_ = null; // encoded token
private int type_ = TYPE_SINGLE_USE;
private int timeoutInterval_ = 3600;
private final static int MAX_USERPROFILE_LENGTH = 10;
final static int MAX_PASSWORD_LENGTH = 128;
/**
ID indicating a single use token.
**/
public final static int TYPE_SINGLE_USE = 1;
/**
ID indicating a multiple use token that cannot be regenerated.
**/
public final static int TYPE_MULTIPLE_USE_NON_RENEWABLE = 2;
/**
ID indicating a multiple use token that can be regenerated.
**/
public final static int TYPE_MULTIPLE_USE_RENEWABLE = 3;
/**
Indicates the length of a profile token (in bytes)
**/
public final static int TOKEN_LENGTH = 32;
/**
* Password special value indicating that the current password is
* not verified.
* The user requesting the profile token must have *USE authority
* to the user profile.
*
This value is not allowed if the name of the currently running
* profile is specified for the user profile name parameter.
*/
public final static int PW_NOPWD = 1; //$A2
/**
* Password special value indicating that a profile token can be
* generated for a profile that is disabled or has an expired password.
*
The user requesting the profile token must have *USE authority to
* the user profile.
*
If the profile is disabled, the user requesting the profile token
* must have *ALLOBJ and *SECADM special authorities to get a token.
*
If the password is expired, the user requesting the profile token
* must have *ALLOBJ and *SECADM special authorities to get a token.
*
If the requesting user does not have *ALLOBJ and *SECADM special
* authorities, then the request will be handled as if they had
* indicated *NOPWD.
*/
public final static int PW_NOPWDCHK = 2; //$A2
/**
* Constructs a ProfileTokenCredential object.
*
*
The system and token must be set
* prior to accessing host information or taking
* action against the credential.
*
*/
public ProfileTokenCredential() {
super();
new Random().nextBytes(addr_);
new Random().nextBytes(mask_);
}
/**
* Constructs and initializes a ProfileTokenCredential object.
*
*
The system, token, tokenType, and
* timeoutInterval properties are initialized to
* the specified values.
*
*
This method allows a credential to be constructed
* based on an existing token (i.e. previously created using the
* QSYGENPT system API). It is the responsibility of the
* application to ensure the tokenType and
* timeoutInterval are consistent with
* the specified token value.
*
* @param system
* The system associated with the credential.
*
* @param token
* The actual bytes for the token as it exists on the
* IBM i system.
*
* @param tokenType
* The type of token provided.
* Possible types are defined as fields on this class:
*
* - TYPE_SINGLE_USE
*
- TYPE_MULTIPLE_USE_NON_RENEWABLE
*
- TYPE_MULTIPLE_USE_RENEWABLE
*
*
* @param timeoutInterval
* The number of seconds to expiration, used as the
* default value when the token is refreshed (1-3600).
*
*/
public ProfileTokenCredential(AS400 system, byte[] token,
int tokenType, int timeoutInterval) {
this();
try {
setSystem(system);
setToken(token);
setTokenType(tokenType);
setTimeoutInterval(timeoutInterval);
}
catch (PropertyVetoException pve) {
AuthenticationSystem.handleUnexpectedException(pve);
}
}
/**
* Decode the bytes based on the adder and mask.
*
* @return
* The decoded byte array.
*
*/
private static byte[] decode(byte[] adder, byte[] mask, byte[] bytes) {
byte[] buf = new byte[bytes.length];
for (int i = 0; i < bytes.length; i++)
buf[i] = (byte)(
(mask[i % mask.length] ^ bytes[i])
- adder[i % adder.length]);
return buf;
}
/**
* Encode the bytes based on the adder and mask.
*
* @return
* The encoded byte array.
*
*/
private static byte[] encode(byte[] adder, byte[] mask, byte[] bytes) {
byte[] buf = new byte[bytes.length];
for (int i = 0; i < bytes.length; i++)
buf[i] = (byte)(
(bytes[i] + adder[i % adder.length])
^ mask[i % mask.length]);
return buf;
}
/**
* Compares the specified Object with the credential
* for equality.
*
* @param o
* Object to be compared for equality.
*
* @return
* true if equal; otherwise false.
*
*/
public boolean equals(Object o) {
if (o == null)
return false;
if (this == o)
return true;
if (!(o instanceof ProfileTokenCredential))
return false;
return
hashCode() == ((ProfileTokenCredential)o).hashCode();
}
/**
* Returns the number of seconds to expiration assigned
* when the token was last initialized or refreshed.
*
* This value also provides the default value for
* subsequent refresh attempts.
*
*
The default value is 3600 (1 hour).
*
* @return
* The number of seconds.
*
*/
public int getTimeoutInterval() {
return timeoutInterval_;
}
/**
* Returns the actual bytes for the token as it exists
* on the IBM i system.
*
* @return
* The token bytes; null if not set.
*
*/
public synchronized byte[] getToken() {
if (token_ != null)
return primitiveGetToken();
return null;
}
/**
* Returns an integer indicating the type assigned when
* the token was last initialized or refreshed.
*
*
This value also provides the default value for
* subsequent refresh attempts.
*
*
The default is TYPE_SINGLE_USE.
*
* @return
* The type of token.
* Possible types are defined as fields on this class:
*
* - TYPE_SINGLE_USE
*
- TYPE_MULTIPLE_USE_NON_RENEWABLE
*
- TYPE_MULTIPLE_USE_RENEWABLE
*
*
*/
public int getTokenType() {
return type_;
}
/**
* Returns the hashcode for the super class @E1A
* @return hashcode for super class
*/
public int superHashCode() {
return super.hashCode();
}
/**
* Returns a hash code for this credential.
*
* @return a hash code for this credential.
*
*/
public int hashCode() {
int hash = 104473;
if (token_ != null) {
// Obtain unencrypted form as common base for comparison
byte[] tkn = getToken();
for (int i=0; i> "
).append(toString()
).append(", for principal >> "
).append(principal.toString()
).append(", isPrivate == "
).append(isPrivate
).append(", isReusable == "
).append(isReusable
).append(", isRenewable == "
).append(isRenewable
).append(", timeoutInterval == "
).append(timeoutInterval
).toString());
// Validate parameters
if (isRenewable && !isReusable) {
Trace.log(Trace.ERROR, "Profile tokens must be multi-use" +
" if declared as regenerable.");
throw new ExtendedIllegalArgumentException("isReusable",
ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID);
}
// Assign to the local host system
AS400 sys = AuthenticationSystem.localHost();
setSystem(sys);
// Assign an appropriate principal
AS400Principal pr =
(AS400Principal.class.isAssignableFrom(principal.getClass()))
? (AS400Principal)principal
: new UserProfilePrincipal(sys, principal.getUserProfileName());
setPrincipal(pr);
// Assign profile token attributes
private_ = isPrivate;
setTimeoutInterval(timeoutInterval);
if (isRenewable) setTokenType(TYPE_MULTIPLE_USE_RENEWABLE);
else if (isReusable) setTokenType(TYPE_MULTIPLE_USE_NON_RENEWABLE);
else setTokenType(TYPE_SINGLE_USE);
// Generate the token
setTokenExtended(pr, password);
}
/**
* Reset the value of all properties used to define
* the credential.
*
* These are the values initialized prior to
* accessing host information for or taking action against
* the credential and not modified thereafter until
* the credential is destroyed.
*
*/
void invalidateProperties() {
super.invalidateProperties();
token_ = null;
}
/**
* Indicates if the credential can be refreshed.
*
* @return
* true if the validity period of the credential
* can be programmatically updated or extended
* using refresh(); otherwise false.
*
* @see #refresh
*/
public boolean isRenewable() {
return type_ == TYPE_MULTIPLE_USE_RENEWABLE;
}
/**
* Indicates if the credential can be used multiple
* times prior to expiration.
*
* @return
* true if the credential can be used to swap
* thread identity multiple times;
* otherwise false.
*
*/
public boolean isReusable() {
return type_ == TYPE_MULTIPLE_USE_NON_RENEWABLE ||
type_ == TYPE_MULTIPLE_USE_RENEWABLE;
}
/**
* Returns the raw bytes for the token represented
* by the credential, decoding the value in
* memory.
*
* @return
* The token bytes.
*
*/
private byte[] primitiveGetToken() {
if (Trace.isTraceOn()) {
Trace.log(Trace.INFORMATION,
"ProfileTokenCredential@"+
Integer.toHexString(this.superHashCode())+ // Note: Calling this.hashCode causes recursion @E1C
" getPrimitiveToken called");
if (!noRefresh) {
// Log the location so we can determine why this is called without refresh tokens locked
// Trace.log(Trace.INFORMATION, new Exception("getPrimitedTokenCalled"));
}
}
return decode(addr_, mask_, token_);
}
/**
* Sets the raw bytes for the token represented
* by the credential, encoding the value in
* memory.
*
* @param bytes
* The token bytes.
*
*/
private void primitiveSetToken(byte[] bytes) {
token_ = encode(addr_, mask_, bytes);
}
/**
* Updates or extends the validity period for the credential.
*
*
Does nothing if the credential cannot be
* programmatically updated or extended.
*
*
Otherwise, generates a new profile token based
* on the previously established token, type,
* and timeoutInterval.
*
* @exception AS400SecurityException
* If an IBM i system security or authentication error occurs.
*
*/
public void refresh() throws AS400SecurityException {
refresh(getTokenType(), getTimeoutInterval());
}
/**
* Updates or extends the validity period for the credential.
*
*
Does nothing if the credential cannot be
* programmatically updated or extended.
*
*
Otherwise, generates a new profile token based on
* the previously established token with the
* given type and timeoutInterval.
*
*
If successful, the specified type and interval
* become the default values for future refresh
* attempts.
*
*
This method is provided to handle cases where it is
* desirable to allow for a more restrictive type of token
* or a different timeout interval when a new token is
* generated during the refresh.
*
* @param type
* The type of token.
* Possible types are defined as fields on this class:
*
* - TYPE_SINGLE_USE
*
- TYPE_MULTIPLE_USE_NON_RENEWABLE
*
- TYPE_MULTIPLE_USE_RENEWABLE
*
*
* @param timeoutInterval
* The number of seconds before expiration (1-3600).
*
* @exception AS400SecurityException
* If an IBM i system security or authentication error occurs.
*
* @exception ExtendedIllegalArgumentException
* If a parameter value is out of range.
*
*/
public synchronized void refresh(int type, int timeoutInterval)
throws AS400SecurityException {
//@D3 - Start The current thread (Refresh Agent thread) is blocked when it receives the message not refreshing.
while(noRefresh){
if (Trace.isTraceOn())
Trace.log(Trace.INFORMATION,
"ProfileTokenCredential@"+
Integer.toHexString(this.hashCode())+
" refresh stuck because of noRefresh");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (Trace.isTraceOn())
Trace.log(Trace.INFORMATION,
"ProfileTokenCredential@"+
Integer.toHexString(this.hashCode())+
" refresh called");
//@D3 - End
// Check permissions
checkAuthenticationPermission("refreshCredential");
// Check status
if (!isRenewable())
return;
// Validate parms
if (type < 1 || type > 3) {
Trace.log(Trace.ERROR, "Token type " + type + " out of range");
throw new ExtendedIllegalArgumentException(
"type", ExtendedIllegalArgumentException.RANGE_NOT_VALID);
}
if (timeoutInterval < 1 || timeoutInterval > 3600) {
Trace.log(Trace.ERROR, "Timeout interval " + timeoutInterval + " out of range");
throw new ExtendedIllegalArgumentException(
"timeoutInterval", ExtendedIllegalArgumentException.RANGE_NOT_VALID);
}
// Refresh the credential
byte[] old = getToken();
byte[] bytes = ((ProfileTokenImpl)getImpl()).refresh(type, timeoutInterval);
primitiveSetToken(bytes);
type_ = type;
timeoutInterval_ = timeoutInterval;
fireRefreshed();
firePropertyChange("token", old, bytes);
if (Trace.isTraceOn())
Trace.log(Trace.INFORMATION,
new StringBuffer("ProfileTokenCredential@"+
Integer.toHexString(this.hashCode())+
" Credential refreshed with type "
).append(type
).append(" and timeoutInterval = "
).append(timeoutInterval
).append(" >> "
).append(toString()
).toString());
}
/**
* Sets the number of seconds to expiration when the
* token is generated or refreshed.
*
* It is the application's responsibility to maintain
* consistency between explicitly set token values (those
* not generated from a user and password) and the
* tokenType and timeoutInterval.
*
*
This property cannot be changed once a request
* initiates a connection for the object to the
* IBM i system (for example, refresh).
*
* @param seconds
* The number of seconds to expiration (1-3600).
*
* @exception PropertyVetoException
* If the change is vetoed.
*
* @exception ExtendedIllegalArgumentException
* If the provided value is out of range.
*
* @exception ExtendedIllegalStateException
* If the property cannot be changed due
* to the current state.
*
*/
public void setTimeoutInterval(int seconds) throws PropertyVetoException {
// Validate state
validatePropertyChange("timeoutInterval");
// Validate parms
if (seconds < 1 || seconds > 3600) {
Trace.log(Trace.ERROR, "Number of seconds " + seconds + " out of range");
throw new ExtendedIllegalArgumentException(
"seconds", ExtendedIllegalArgumentException.RANGE_NOT_VALID);
}
Integer old = new Integer(timeoutInterval_);
Integer sec = new Integer(seconds);
fireVetoableChange("timeoutInterval", old, sec);
timeoutInterval_ = seconds;
firePropertyChange("timeoutInterval", old, sec);
}
/**
* Sets the actual bytes for the token as it exists
* on the IBM i system.
*
*
This method allows a credential to be constructed
* based on an existing token (i.e. previously created using the
* QSYGENPT system API). It is the responsibility of the
* application to ensure the tokenType and
* timeoutInterval are consistent with
* the specified token value.
*
*
This property cannot be changed once a request
* initiates a connection for the object to the
* IBM i system (for example, refresh).
*
* @param bytes
* The token bytes.
*
* @exception PropertyVetoException
* If the change is vetoed.
*
* @exception ExtendedIllegalArgumentException
* If the provided value is not the correct
* length.
*
* @exception ExtendedIllegalStateException
* If the property cannot be changed due
* to the current state.
*
*/
public synchronized void setToken(byte[] bytes) throws PropertyVetoException {
// Validate state
validatePropertyChange("token");
// Validate parms
if (bytes == null) {
Trace.log(Trace.ERROR, "Token byte array is null");
throw new ExtendedIllegalArgumentException(
"bytes", ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID);
}
if (bytes.length != TOKEN_LENGTH) {
Trace.log(Trace.ERROR, "Token of length " + bytes.length +
" not valid ");
throw new ExtendedIllegalArgumentException(
"bytes", ExtendedIllegalArgumentException.LENGTH_NOT_VALID);
}
byte[] old = getToken();
fireVetoableChange("token", old, bytes);
primitiveSetToken(bytes);
firePropertyChange("token", old, bytes);
}
/**
* Sets the token bytes based on the provided principal and password.
*
*
The system property must be set prior to
* invoking this method.
*
*
If successful, this method results in a new token being created
* on the IBM i system. The new token is generated using the
* previously established tokenType and timeoutInterval
* settings.
*
*
This property cannot be changed once a request
* initiates a connection for the object to the
* IBM i system (for example, refresh).
*
* @deprecated As of V5R3, replaced
* by {@link #setTokenExtended(AS400Principal,String)} for password strings
* or {@link #setToken(AS400Principal,int)} for password special values.
*
* @param principal
* The principal identifying the user profile for
* which the token is to be generated.
*
* @param password
* The user profile password. The following special values are allowed:
*
* - *NOPWD - The password is not verified. This value is not
* allowed if the name of the currently running profile is
* specified for the name parameter. If specified, the user
* requesting the profile token must have *USE authority to
* the user profile.
* - *NOPWDCHK - The password is not verified. This value allows
* a profile token to be generated for a profile that is disabled
* or has an expired password. If disabled or expired, the user
* requesting the profile token must have *ALLOBJ and *SECADM
* special authority.
*
*
* @exception AS400SecurityException
* If an IBM i system security or authentication error occurs.
*
* @exception PropertyVetoException
* If the change is vetoed.
*
* @exception ExtendedIllegalArgumentException
* If errors occur during parameter validation.
*
* @exception ExtendedIllegalStateException
* If the token cannot be initialized due
* to the current state.
*
*/
public void setToken(AS400Principal principal, String password)
throws PropertyVetoException, AS400SecurityException {
setToken(principal.getUserProfileName(), password);
}
/**
* Sets the token bytes based on the provided user profile and password.
*
* The system property must be set prior to
* invoking this method.
*
*
If successful, this method results in a new token being created
* on the IBM i system. The new token is generated using the
* previously established tokenType and timeoutInterval
* settings.
*
*
This property cannot be changed once a request
* initiates a connection for the object to the
* IBM i system (for example, refresh).
*
* @deprecated As of V5R3, replaced
* by {@link #setTokenExtended(String,String)} for password strings
* or {@link #setToken(String,int)} for password special values.
*
* @param name
* The name of the user profile for which the token
* is to be generated.
*
* @param password
* The user profile password. The following special values are allowed:
*
* - *NOPWD - The password is not verified. This value is not
* allowed if the name of the currently running profile is
* specified for the name parameter. If specified, the user
* requesting the profile token must have *USE authority to
* the user profile.
* - *NOPWDCHK - The password is not verified. This value allows
* a profile token to be generated for a profile that is disabled
* or has an expired password. If disabled or expired, the user
* requesting the profile token must have *ALLOBJ and *SECADM
* special authority.
*
*
* @exception AS400SecurityException
* If an IBM i system security or authentication error occurs.
*
* @exception PropertyVetoException
* If the change is vetoed.
*
* @exception ExtendedIllegalArgumentException
* If errors occur during parameter validation.
*
* @exception ExtendedIllegalStateException
* If the token cannot be initialized due
* to the current state.
*
*/
public void setToken(String name, String password)
throws PropertyVetoException, AS400SecurityException {
// Validate state
validatePropertySet("system", getSystem());
// Validate name and password parameters
if (name == null) {
Trace.log(Trace.ERROR, "User profile name is null");
throw new ExtendedIllegalArgumentException(
"name", ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID);
}
if (name.length() > MAX_USERPROFILE_LENGTH) {
Trace.log(Trace.ERROR, "User profile name exceeds" +
" maximum allowed length");
throw new ExtendedIllegalArgumentException(
"name", ExtendedIllegalArgumentException.LENGTH_NOT_VALID);
}
if (password == null) {
Trace.log(Trace.ERROR, "User profile password is null");
throw new ExtendedIllegalArgumentException(
"password",
ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID);
}
// Instantiate a new impl but do not yet set as the default impl_
ProfileTokenImpl impl = (ProfileTokenImpl)getImplPrimitive();
// Generate and set the token value
setToken(
impl.generateToken(
name,
password,
getTokenType(),
getTimeoutInterval()));
// If successful, all defining attributes are now set.
// Set the impl for subsequent references.
setImpl(impl);
// Indicate that a new token was created.
fireCreated();
}
//$A2
/**
* Sets the token bytes based on the provided principal and
* special value for a password.
*
* This method requires a special value to be specified for
* the user password parameter. If you need to validate a user password,
* see the {@link #setTokenExtended(AS400Principal, String)}.
*
*
The system property must be set prior to invoking this method.
*
*
If successful, this method results in a new token being created
* on the IBM i system. The new token is generated using the
* previously established tokenType and timeoutInterval
* settings.
*
*
This property cannot be changed once a request
* initiates a connection for the object to the
* IBM i system (for example, refresh).
*
* @param principal
* The principal identifying the user profile for
* which the token is to be generated.
*
* @param passwordSpecialValue
* The special value for the user profile password.
* The following special values are allowed:
*
* - PW_NOPWD - The password is not verified. This value is not
* allowed if the name of the currently running profile is
* specified for the name parameter. If specified, the user
* requesting the profile token must have *USE authority to
* the user profile.
* - PW_NOPWDCHK - The password is not verified. This value allows
* a profile token to be generated for a profile that is disabled
* or has an expired password. If specified, the user
* requesting the profile token must have *USE authority to
* the user profile. If disabled or expired, the user
* requesting the profile token must have *ALLOBJ and *SECADM
* special authority.
*
*
* @exception AS400SecurityException
* If an IBM i system security or authentication error occurs.
*
* @exception PropertyVetoException
* If the change is vetoed.
*
* @exception ExtendedIllegalArgumentException
* If errors occur during parameter validation.
*
* @exception ExtendedIllegalStateException
* If the token cannot be initialized due
* to the current state.
*
*/
public void setToken(AS400Principal principal, int passwordSpecialValue)
throws PropertyVetoException, AS400SecurityException {
setToken(principal.getUserProfileName(), passwordSpecialValue);
}
//$A2
/**
* Sets the token bytes based on the provided user profile and
* special value for a password.
*
* This method requires a special value to be specified for
* the user password parameter. If you need to validate a user
* password, see the {@link #setTokenExtended(String, String)}.
*
*
The system property must be set prior to invoking this method.
*
*
If successful, this method results in a new token being created
* on the IBM i system. The new token is generated using the
* previously established tokenType and timeoutInterval
* settings.
*
*
This property cannot be changed once a request
* initiates a connection for the object to the
* IBM i system (for example, refresh).
*
* @param name
* The name of the user profile for which the token
* is to be generated.
*
* @param passwordSpecialValue
* The special value for the user profile password.
* The following special values are allowed:
*
* - PW_NOPWD - The password is not verified. This value is not
* allowed if the name of the currently running profile is
* specified for the name parameter. If specified, the user
* requesting the profile token must have *USE authority to
* the user profile.
* - PW_NOPWDCHK - The password is not verified. This value allows
* a profile token to be generated for a profile that is disabled
* or has an expired password. If specified, the user
* requesting the profile token must have *USE authority to
* the user profile. If disabled or expired, the user
* requesting the profile token must have *ALLOBJ and *SECADM
* special authority.
*
*
* @exception AS400SecurityException
* If an IBM i system security or authentication error occurs.
*
* @exception PropertyVetoException
* If the change is vetoed.
*
* @exception ExtendedIllegalArgumentException
* If errors occur during parameter validation.
*
* @exception ExtendedIllegalStateException
* If the token cannot be initialized due
* to the current state.
*
*/
public void setToken(String name, int passwordSpecialValue)
throws PropertyVetoException, AS400SecurityException {
// Validate state
validatePropertySet("system", getSystem());
// Validate name
if (name == null) {
Trace.log(Trace.ERROR, "User profile name is null");
throw new ExtendedIllegalArgumentException(
"name", ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID);
}
if (name.length() > MAX_USERPROFILE_LENGTH) {
Trace.log(Trace.ERROR, "User profile name exceeds " +
"maximum allowed length");
throw new ExtendedIllegalArgumentException(
"name", ExtendedIllegalArgumentException.LENGTH_NOT_VALID);
}
// Validate special value for password
switch (passwordSpecialValue) {
case PW_NOPWD:
case PW_NOPWDCHK:
break;
default:
Trace.log(Trace.ERROR, "Special value for password is not valid");
throw new ExtendedIllegalArgumentException(
"password",
ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID);
}
// Instantiate a new impl but do not yet set as the default impl_
ProfileTokenImpl impl = (ProfileTokenImpl)getImplPrimitive();
// Generate and set the token value
setToken(
impl.generateToken(
name,
passwordSpecialValue,
getTokenType(),
getTimeoutInterval()));
// If successful, all defining attributes are now set.
// Set the impl for subsequent references.
setImpl(impl);
// Indicate that a new token was created.
fireCreated();
}
//$A2
/**
* Sets the token bytes based on the provided principal and password.
*
* The system property must be set prior to
* invoking this method.
*
*
If successful, this method results in a new token being created
* on the IBM i system. The new token is generated using the
* previously established tokenType and timeoutInterval
* settings.
*
*
This property cannot be changed once a request
* initiates a connection for the object to the
* IBM i system (for example, refresh).
*
* @param principal
* The principal identifying the user profile for
* which the token is to be generated.
*
* @param password
* The user profile password.
*
* @exception AS400SecurityException
* If an IBM i system security or authentication error occurs.
*
* @exception PropertyVetoException
* If the change is vetoed.
*
* @exception ExtendedIllegalArgumentException
* If errors occur during parameter validation.
*
* @exception ExtendedIllegalStateException
* If the token cannot be initialized due
* to the current state.
*
*/
public void setTokenExtended(AS400Principal principal, String password)
throws PropertyVetoException, AS400SecurityException {
setTokenExtended(principal.getUserProfileName(), password);
}
//$A2
/**
* Sets the token bytes based on the provided user profile and password.
*
*
The system property must be set prior to
* invoking this method.
*
*
If successful, this method results in a new token being created
* on the IBM i system. The new token is generated using the
* previously established tokenType and timeoutInterval
* settings.
*
*
This property cannot be changed once a request
* initiates a connection for the object to the
* IBM i system (for example, refresh).
*
* @param name
* The name of the user profile for which the token
* is to be generated.
*
* @param password
* The user profile password.
*
* @exception AS400SecurityException
* If an IBM i system security or authentication error occurs.
*
* @exception PropertyVetoException
* If the change is vetoed.
*
* @exception ExtendedIllegalArgumentException
* If errors occur during parameter validation.
*
* @exception ExtendedIllegalStateException
* If the token cannot be initialized due
* to the current state.
*
*/
public void setTokenExtended(String name, String password)
throws PropertyVetoException, AS400SecurityException {
// Validate state
validatePropertySet("system", getSystem());
// Validate name and password parameters
if (name == null) {
Trace.log(Trace.ERROR, "User profile name is null");
throw new ExtendedIllegalArgumentException("name",
ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID);
}
if (name.length() > MAX_USERPROFILE_LENGTH) {
Trace.log(Trace.ERROR, "User profile name exceeds " +
"maximum allowed length");
throw new ExtendedIllegalArgumentException("name",
ExtendedIllegalArgumentException.LENGTH_NOT_VALID);
}
if (password == null) {
Trace.log(Trace.ERROR, "User profile password is null");
throw new ExtendedIllegalArgumentException("password",
ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID);
}
// Instantiate a new impl but do not yet set as the default impl_
ProfileTokenImpl impl = (ProfileTokenImpl)getImplPrimitive();
// Generate and set the token value
setToken(
impl.generateTokenExtended(
name,
password,
getTokenType(),
getTimeoutInterval()));
// If successful, all defining attributes are now set.
// Set the impl for subsequent references.
setImpl(impl);
// Indicate that a new token was created.
fireCreated();
}
/**
* Sets the type of token.
*
*
It is the application's responsibility to maintain
* consistency between explicitly set token values (those
* not generated from a user and password) and the
* tokenType and timeoutInterval.
*
*
This property cannot be changed once a request
* initiates a connection for the object to the
* IBM i system (for example, refresh).
*
* @param type
* The type of token.
* Possible types are defined as fields on this class:
*
* - TYPE_SINGLE_USE
*
- TYPE_MULTIPLE_USE_NON_RENEWABLE
*
- TYPE_MULTIPLE_USE_RENEWABLE
*
*
* @exception PropertyVetoException
* If the change is vetoed.
*
* @exception ExtendedIllegalArgumentException
* If the provided value is out of range.
*
* @exception ExtendedIllegalStateException
* If the property cannot be changed due
* to the current state.
*
*/
public void setTokenType(int type) throws PropertyVetoException {
// Validate state
validatePropertyChange("tokenType");
// Validate parms
if (type < 1 || type > 3) {
Trace.log(Trace.ERROR, "Token type " + type + " out of range");
throw new ExtendedIllegalArgumentException(
"type", ExtendedIllegalArgumentException.RANGE_NOT_VALID);
}
Integer old = new Integer(type_);
Integer typ = new Integer(type);
fireVetoableChange("tokenType", old, typ);
type_ = type;
firePropertyChange("tokenType", old, typ);
}
/**
* Returns a string representation of the object
*
* @return a string representation of the object.
*/
public String toString() {
return new StringBuffer(256
).append(super.toString()
).append('['
).append(getTokenType()
).append(','
).append(getTimeoutInterval()
).append(']'
).toString();
}
/**
* Indicates if instances of the class are sufficient
* by themselves to change the OS thread identity.
*
* Typically this behavior is dictated by the type
* of credential and need not be changed for
* individual instances.
*
* @return
* true
*
*/
boolean typeIsStandalone() {
return true;
}
/**
* Indicates if instances of the class will expire based on time.
*
*
Typically this behavior is dictated by the type
* of credential and need not be changed for
* individual instances.
*
* @return
* true
*/
boolean typeIsTimed() {
return true;
}
/**
* Validates that all properties required to define the
* credential have been set.
*
*
These are the values initialized prior to
* accessing host information for or taking action against
* the credential and not modified thereafter until
* the credential is destroyed.
*
* @exception ExtendedIllegalStateException
* If a required property is not set.
*
*/
void validateProperties() {
super.validateProperties();
validatePropertySet("token", getToken());
}
//@D3A - Start
/**
* Block the thread to refresh profile token credential.
* @throws InterruptedException
*/
public synchronized void preventRefresh() throws InterruptedException {
if (Trace.isTraceOn())
Trace.log(Trace.INFORMATION,
"ProfileTokenCredential@"+
Integer.toHexString(this.hashCode())+
" preventRefresh");
noRefresh = true;
}
private boolean noRefresh = false;
/**
* Notify the wait thread to refresh profile token credential.
*/
public synchronized void allowRefresh() {
if (Trace.isTraceOn())
Trace.log(Trace.INFORMATION,
"ProfileTokenCredential@"+
Integer.toHexString(this.hashCode())+
" allowRefresh");
noRefresh = false;
notify();
}
//@D3A - End
}