From b47312c790025f623b65197d6801240437a52d48 Mon Sep 17 00:00:00 2001 From: Nadir K Amra Date: Thu, 15 Aug 2024 19:51:57 -0500 Subject: [PATCH 1/2] User handle, doc reformatting, GUI MFA changes, DDM factor support Signed-off-by: Nadir K Amra --- src/main/java/com/ibm/as400/access/AS400.java | 2581 ++++++++++------- .../ibm/as400/access/AS400GenAuthTknDS.java | 72 +- .../com/ibm/as400/access/AS400ImplRemote.java | 441 ++- .../com/ibm/as400/access/AS400StrSvrDS.java | 17 +- .../as400/access/ChangePasswordDialog.java | 53 +- .../ibm/as400/access/ChangePasswordReq.java | 27 +- .../com/ibm/as400/access/ClassDecoupler.java | 10 +- .../java/com/ibm/as400/access/CoreMRI.java | 1 + .../access/DDMSECCHKRequestDataStream.java | 36 +- .../as400/access/IFSCreateUserHandlerReq.java | 56 +- .../java/com/ibm/as400/access/IFSFile.java | 240 +- .../access/IFSFileDescriptorImplRemote.java | 859 +++--- .../ibm/as400/access/IFSFileImplRemote.java | 41 - .../ibm/as400/access/IFSUserHandle2Req.java | 53 +- .../com/ibm/as400/access/PasswordDialog.java | 58 +- .../as400/access/ProfileTokenImplNative.java | 263 +- .../ibm/as400/access/ProfileTokenVault.java | 9 + .../ibm/as400/access/ProgramParameter.java | 5 +- .../com/ibm/as400/access/SignonInfoReq.java | 20 +- .../as400/access/ToolboxSignonHandler.java | 1232 ++++---- .../AS400BasicAuthenticationCredential.java | 175 +- .../security/auth/ProfileTokenCredential.java | 220 +- .../security/auth/ProfileTokenImplRemote.java | 373 +-- 23 files changed, 3370 insertions(+), 3472 deletions(-) diff --git a/src/main/java/com/ibm/as400/access/AS400.java b/src/main/java/com/ibm/as400/access/AS400.java index e10293498..9e6f87dc3 100644 --- a/src/main/java/com/ibm/as400/access/AS400.java +++ b/src/main/java/com/ibm/as400/access/AS400.java @@ -41,23 +41,25 @@ import com.ibm.as400.security.auth.ProfileTokenProvider; /** - Represents the authentication information and a set of connections to the IBM i host servers. -

If running on IBM i or an older version of that operating system, the system name, user ID, - and password do not need to be supplied. These values default to the local system. - For the system name, the keyword localhost can be used to specify the local system. - For the user ID and password, *CURRENT can be used. -

If running on another operating system, the system name, user ID, and password need to be supplied. - If not supplied, the first 'open' request associated with this object will trigger a prompt to the - workstation user. Subsequent opens associated with the same object will not prompt the workstation - user. Keywords localhost and *CURRENT will not work when running on another operating - system. -

For example: -

- *    AS400 system = new AS400();
- *    system.connectService(AS400.DATAQUEUE);   // This causes a password prompt.
- *    ...
- *    system.connectService(AS400.FILE);        // This does not cause a prompt.
- 
+ * Represents the authentication information and a set of connections to the IBM i host servers. + *

+ * If running on IBM i or an older version of that operating system, the system name, user ID, and password do not need + * to be supplied. These values default to the local system. For the system name, the keyword localhost can + * be used to specify the local system. For the user ID and password, *CURRENT can be used. + *

+ * If running on another operating system, the system name, user ID, and password need to be supplied. If not supplied, + * the first 'open' request associated with this object will trigger a prompt to the workstation user. Subsequent opens + * associated with the same object will not prompt the workstation user. Keywords localhost and *CURRENT + * will not work when running on another operating system. + *

+ * For example: + * + *

+      AS400 system = new AS400();
+      system.connectService(AS400.DATAQUEUE);   // This causes a password prompt.
+      ...
+      system.connectService(AS400.FILE);        // This does not cause a prompt.
+ * 
**/ public class AS400 implements Serializable, AutoCloseable { @@ -421,11 +423,13 @@ public class AS400 implements Serializable, AutoCloseable private int validateSignonTimeOut_ = 0; /** - Constructs an AS400 object. -

If running on IBM i, the target is the local system. This has the same effect as using localhost - for the system name, *CURRENT for the user ID, and *CURRENT for the password. -

If running on another operating system, a sign-on prompt may be displayed. The user is then able to specify - the system name, user ID, and password. + * Constructs an AS400 object. + *

+ * If running on IBM i, the target is the local system. This has the same effect as using localhost for + * the system name, *CURRENT for the user ID, and *CURRENT for the password. + *

+ * If running on another operating system, a sign-on prompt may be displayed. The user is then able to specify the + * system name, user ID, and password. **/ public AS400() { @@ -440,11 +444,14 @@ public AS400() } /** - Constructs an AS400 object. It uses the specified system name. -

If running on IBM i to another system or to itself, the user ID and password of the current job are used. -

If running on another operating system, the user may be prompted for the user ID and password if a default - user has not been established for this system name. - @param systemName The name of the IBM i system. Use localhost to access data locally. + * Constructs an AS400 object. It uses the specified system name. + *

+ * If running on IBM i to another system or to itself, the user ID and password of the current job are used. + *

+ * If running on another operating system, the user may be prompted for the user ID and password if a default user + * has not been established for this system name. + * + * @param systemName The name of the IBM i system. Use localhost to access data locally. **/ public AS400(String systemName) { @@ -463,11 +470,12 @@ public AS400(String systemName) } /** - Constructs an AS400 object. It uses the specified system name and user ID. If the sign-on prompt is displayed, - the user is able to specify the password. Note that the user ID may be overridden. - @param systemName The name of the IBM i system. Use localhost to access data locally. - @param userId The user profile name to use to authenticate to the system. If running on IBM i, *CURRENT may - be used to specify the current user ID. + * Constructs an AS400 object. It uses the specified system name and user ID. If the sign-on prompt is displayed, + * the user is able to specify the password. Note that the user ID may be overridden. + * + * @param systemName The name of the IBM i system. Use localhost to access data locally. + * @param userId The user profile name to use to authenticate to the system. If running on IBM i, *CURRENT may + * be used to specify the current user ID. **/ public AS400(String systemName, String userId) { @@ -499,9 +507,10 @@ public AS400(String systemName, String userId) } /** - Constructs an AS400 object. It uses the specified system name and profile token. - @param systemName The name of the IBM i system. Use localhost to access data locally. - @param profileToken The profile token to use to authenticate to the system. + * Constructs an AS400 object. It uses the specified system name and profile token. + * + * @param systemName The name of the IBM i system. Use localhost to access data locally. + * @param profileToken The profile token to use to authenticate to the system. **/ public AS400(String systemName, ProfileTokenCredential profileToken) { @@ -516,9 +525,10 @@ public AS400(String systemName, ProfileTokenCredential profileToken) } /** - * Constructs an AS400 object. The specified ProfileTokenProvider is used. - * The token refresh threshold is determined by the ProfileTokenProvider. - * @param systemName The name of the IBM i system. + * Constructs an AS400 object. The specified ProfileTokenProvider is used. The token refresh threshold is determined + * by the ProfileTokenProvider. + * + * @param systemName The name of the IBM i system. * @param tokenProvider The provider to use when a new profile token needs to be generated. * @see #AS400(String,ProfileTokenProvider,int) */ @@ -527,12 +537,13 @@ public AS400(String systemName, ProfileTokenProvider tokenProvider) { } /** - * Constructs an AS400 object. The specified ProfileTokenProvider is used. - * @param systemName The name of the IBM i system. - * @param tokenProvider The provider to use when a new profile token needs to be generated. - * @param refreshThreshold The refresh threshold, in seconds, for the profile token. - * Used by the vault to manage the currency of the profile token - * to help ensure it remains current for an indefinite period of time. + * Constructs an AS400 object. The specified ProfileTokenProvider is used. + * + * @param systemName The name of the IBM i system. + * @param tokenProvider The provider to use when a new profile token needs to be generated. + * @param refreshThreshold The refresh threshold, in seconds, for the profile token. Used by the vault to manage the + * currency of the profile token to help ensure it remains current for an indefinite period + * of time. * @see #AS400(String,ProfileTokenProvider) */ public AS400(String systemName, ProfileTokenProvider tokenProvider, int refreshThreshold) { @@ -549,11 +560,9 @@ private AS400(String systemName, ProfileTokenProvider tokenProvider, Integer ref if (PASSWORD_TRACE) Trace.log(Trace.DIAGNOSTIC, "profile token provider:", tokenProvider.getClass().getName()); - // Was a refresh threshold specified? - if (refreshThreshold != null) - constructWithProfileToken(systemName, new ManagedProfileTokenVault(tokenProvider, refreshThreshold.intValue())); - else - constructWithProfileToken(systemName, new ManagedProfileTokenVault(tokenProvider)); + constructWithProfileToken(systemName, (refreshThreshold != null) + ? new ManagedProfileTokenVault(tokenProvider, refreshThreshold.intValue()) + : new ManagedProfileTokenVault(tokenProvider)); } /** @@ -575,15 +584,17 @@ private void constructWithProfileToken(String systemName, ProfileTokenVault cred } /** - Constructs an AS400 object. It uses the specified system name, user ID, and password. No sign-on prompt is - displayed unless the sign-on fails. - @param systemName The name of the IBM i system. Use localhost to access data locally. - @param userId The user profile name to use to authenticate to the system. If running on IBM i, *CURRENT may be - used to specify the current user ID. - @param password The user profile password to use to authenticate to the system. If running on IBM i, - *CURRENT may be used to specify the current user ID. - @deprecated Use AS400(String systemName, String userId, char[] password) instead - **/ + * Constructs an AS400 object. It uses the specified system name, user ID, and password. No sign-on prompt is + * displayed unless the sign-on fails. + * + * @param systemName The name of the IBM i system. Use localhost to access data locally. + * @param userId The user profile name to use to authenticate to the system. If running on IBM i, *CURRENT may + * be used to specify the current user ID. + * @param password The user profile password to use to authenticate to the system. If running on IBM i, CURRENT + * may be used to specify the current user ID. + * @deprecated Use AS400(String systemName, String userId, char[] password) instead + **/ + @Deprecated public AS400(String systemName, String userId, String password) { super(); @@ -624,29 +635,34 @@ public AS400(String systemName, String userId, String password) } /** - Constructs an AS400 object. It uses the specified system name, user ID, password, and additional authentication - factor. No sign-on prompt is displayed unless the sign-on fails. - @param systemName The name of the IBM i system. Use localhost to access data locally. - @param userId The user profile name to use to authenticate to the system. If running on IBM i, *CURRENT - may be used to specify the current user ID. - @param password The user profile password to use to authenticate to the system. - @param additionalAuthenticationFactor Additional authentication factor (or null if not providing one). - The caller is responsible for clearing the password array to keep the password from residing in memory. - **/ - public AS400(String systemName, String userId, char[] password, char[] additionalAuthenticationFactor) throws AS400SecurityException, IOException + * Constructs an AS400 object. It uses the specified system name, user ID, password, and additional authentication + * factor. No sign-on prompt is displayed unless the sign-on fails. + * + * @param systemName The name of the IBM i system. Use localhost to access data locally. + * @param userId The user profile name to use to authenticate to the system. If running on IBM i, + * *CURRENT may be used to specify the current user ID. + * @param password The user profile password to use to authenticate to the system. + * @param additionalAuthFactor Additional authentication factor (or null if not providing one). The caller is + * responsible for clearing the password array to keep the password from residing in + * memory. + * @throws AS400SecurityException If a security or authority error occurs. + * @throws IOException If an error occurs while communicating with the system. + **/ + public AS400(String systemName, String userId, char[] password, char[] additionalAuthFactor) throws AS400SecurityException, IOException { this(systemName, userId, password); - setAdditionalAuthenticationFactor(additionalAuthenticationFactor); + setAdditionalAuthenticationFactor(additionalAuthFactor); } /** - Constructs an AS400 object. It uses the specified system name, user ID, and password. No sign-on prompt - is displayed unless the sign-on fails. - @param systemName The name of the IBM i system. Use localhost to access data locally. - @param userId The user profile name to use to authenticate to the system. If running on IBM i, *CURRENT - may be used to specify the current user ID. - @param password The user profile password to use to authenticate to the system. - The caller is responsible for clearing the password array to keep the password from residing in memory. + * Constructs an AS400 object. It uses the specified system name, user ID, and password. No sign-on prompt is + * displayed unless the sign-on fails. + * + * @param systemName The name of the IBM i system. Use localhost to access data locally. + * @param userId The user profile name to use to authenticate to the system. If running on IBM i, *CURRENT may + * be used to specify the current user ID. + * @param password The user profile password to use to authenticate to the system. The caller is responsible for + * clearing the password array to keep the password from residing in memory. **/ public AS400(String systemName, String userId, char[] password) { @@ -687,19 +703,19 @@ public AS400(String systemName, String userId, char[] password) public String aspName=""; /** - * Set ASP group for the AS400 connection to the Remote Command Host server. It calls SETASPGRP command to - * change the asp setting for corresponding CommandCall, ProgramCall and ServiceProgramCall in the same connection. - * Current library default is *CURUSR. - * Libraries for current thread default is *CURUSR. - * If an ASP group had already been set, it will remove the old ASP group and set the specified ASP group for the current thread. - * Once the specified ASP group has been set, all libraries in the independent ASPs in the ASP group are accessible - * and objects in those libraries can be referenced using regular library-qualified object name syntax. + * Set ASP group for the AS400 connection to the Remote Command Host server. It calls SETASPGRP command to change + * the asp setting for corresponding CommandCall, ProgramCall and ServiceProgramCall in the same connection. Current + * library default is *CURUSR. Libraries for current thread default is *CURUSR. If an ASP group had already been + * set, it will remove the old ASP group and set the specified ASP group for the current thread. Once the specified + * ASP group has been set, all libraries in the independent ASPs in the ASP group are accessible and objects in + * those libraries can be referenced using regular library-qualified object name syntax. + * * @param IASPGroup asp group name - * @throws AS400SecurityException If a security or authority error occurs. - * @throws ErrorCompletingRequestException If an error occurs before the request is completed. - * @throws IOException If an error occurs while communicating with the system. - * @throws InterruptedException If this thread is interrupted. - * @throws PropertyVetoException If the recipient wishes the property change to be rolled back. + * @throws AS400SecurityException If a security or authority error occurs. + * @throws ErrorCompletingRequestException If an error occurs before the request is completed. + * @throws IOException If an error occurs while communicating with the system. + * @throws InterruptedException If this thread is interrupted. + * @throws PropertyVetoException If the recipient wishes the property change to be rolled back. */ public void setIASPGroup(String IASPGroup) throws AS400SecurityException, ErrorCompletingRequestException, IOException, InterruptedException, PropertyVetoException { @@ -716,19 +732,21 @@ public void setIASPGroup(String IASPGroup) throws AS400SecurityException, ErrorC } /** - * Set ASP group for the AS400 connection to the Remote Command Host server. It calls SETASPGRP command to - * change the asp setting for corresponding CommandCall, ProgramCall and ServiceProgramCall in the same connection. - * Libraries for current thread default is *CURUSR. - * If an ASP group had already been set, it will remove the old ASP group and set the specified ASP group for the current thread. - * Once the specified ASP group has been set, all libraries in the independent ASPs in the ASP group are accessible - * and objects in those libraries can be referenced using regular library-qualified object name syntax. - * @param IASPGroup asp group name - * @param currentLib Current library which can be *CURSYSBAS, *CURUSR, *CRTDFT, name. If null or "" is set, default value *CURUSR is used. - * @throws AS400SecurityException If a security or authority error occurs. - * @throws ErrorCompletingRequestException If an error occurs before the request is completed. - * @throws IOException If an error occurs while communicating with the system. - * @throws InterruptedException If this thread is interrupted. - * @throws PropertyVetoException If the recipient wishes the property change to be rolled back. + * Set ASP group for the AS400 connection to the Remote Command Host server. It calls SETASPGRP command to change + * the asp setting for corresponding CommandCall, ProgramCall and ServiceProgramCall in the same connection. + * Libraries for current thread default is *CURUSR. If an ASP group had already been set, it will remove the old ASP + * group and set the specified ASP group for the current thread. Once the specified ASP group has been set, all + * libraries in the independent ASPs in the ASP group are accessible and objects in those libraries can be + * referenced using regular library-qualified object name syntax. + * + * @param IASPGroup asp group name + * @param currentLib Current library which can be *CURSYSBAS, *CURUSR, *CRTDFT, name. If null or "" is set, default + * value *CURUSR is used. + * @throws AS400SecurityException If a security or authority error occurs. + * @throws ErrorCompletingRequestException If an error occurs before the request is completed. + * @throws IOException If an error occurs while communicating with the system. + * @throws InterruptedException If this thread is interrupted. + * @throws PropertyVetoException If the recipient wishes the property change to be rolled back. */ public void setIASPGroup(String IASPGroup, String currentLib) throws AS400SecurityException, ErrorCompletingRequestException, IOException, InterruptedException, PropertyVetoException { @@ -750,18 +768,24 @@ else if (currentLib.length() > 10) } else aspName = IASPGroup; } + /** - * Set ASP group for the AS400 connection to the Remote Command Host server. It calls SETASPGRP command to change the asp setting for corresponding CommandCall, ProgramCall and ServiceProgramCall in the same connection. - * If an ASP group had already been set, it will remove the old ASP group and set the specified ASP group for the current thread. - * Once the specified ASP group has been set, all libraries in the independent ASPs in the ASP group are accessible and objects in those libraries can be referenced using regular library-qualified object name syntax. - * @param IASPGroup asp group name - * @param currentLib Current library which can be *CURSYSBAS, *CURUSR, *CRTDFT, name. If null or "" is set, default value *CURUSR is used. - * @param librariesForThread Libraries for current thread with single value. If null or "" is set, default value *CURUSR is used. - * @throws AS400SecurityException If a security or authority error occurs. - * @throws ErrorCompletingRequestException If an error occurs before the request is completed. - * @throws IOException If an error occurs while communicating with the system. - * @throws InterruptedException If this thread is interrupted. - * @throws PropertyVetoException If the recipient wishes the property change to be rolled back. + * Set ASP group for the AS400 connection to the Remote Command Host server. It calls SETASPGRP command to change + * the asp setting for corresponding CommandCall, ProgramCall and ServiceProgramCall in the same connection. If an + * ASP group had already been set, it will remove the old ASP group and set the specified ASP group for the current + * thread. Once the specified ASP group has been set, all libraries in the independent ASPs in the ASP group are + * accessible and objects in those libraries can be referenced using regular library-qualified object name syntax. + * + * @param IASPGroup asp group name + * @param currentLib Current library which can be *CURSYSBAS, *CURUSR, *CRTDFT, name. If null or "" is set, + * default value *CURUSR is used. + * @param librariesForThread Libraries for current thread with single value. If null or "" is set, default value + * *CURUSR is used. + * @throws AS400SecurityException If a security or authority error occurs. + * @throws ErrorCompletingRequestException If an error occurs before the request is completed. + * @throws IOException If an error occurs while communicating with the system. + * @throws InterruptedException If this thread is interrupted. + * @throws PropertyVetoException If the recipient wishes the property change to be rolled back. */ public void setIASPGroup(String IASPGroup, String currentLib, String librariesForThread) throws AS400SecurityException, ErrorCompletingRequestException, IOException, InterruptedException, PropertyVetoException { @@ -794,17 +818,22 @@ else if (librariesForThread.length() > 10) } /** - * Set ASP group for the AS400 connection to the Remote Command Host server. It calls SETASPGRP command to change the asp setting for corresponding CommandCall, ProgramCall and ServiceProgramCall in the same connection. - * If an ASP group had already been set, it will remove the old ASP group and set the specified ASP group for the current thread. - * Once the specified ASP group has been set, all libraries in the independent ASPs in the ASP group are accessible and objects in those libraries can be referenced using regular library-qualified object name syntax. - * @param IASPGroup asp group name - * @param currentLib Current library which can be *CURSYSBAS, *CURUSR, *CRTDFT, name. If null or "" is set, default value *CURUSR is used. - * @param librariesForThread Libraries for current thread. If null is set, default value *CURUSR is used. Up to 250 libraries can be set. - * @throws AS400SecurityException If a security or authority error occurs. - * @throws ErrorCompletingRequestException If an error occurs before the request is completed. - * @throws IOException If an error occurs while communicating with the system. - * @throws InterruptedException If this thread is interrupted. - * @throws PropertyVetoException If the recipient wishes the property change to be rolled back. + * Set ASP group for the AS400 connection to the Remote Command Host server. It calls SETASPGRP command to change + * the asp setting for corresponding CommandCall, ProgramCall and ServiceProgramCall in the same connection. If an + * ASP group had already been set, it will remove the old ASP group and set the specified ASP group for the current + * thread. Once the specified ASP group has been set, all libraries in the independent ASPs in the ASP group are + * accessible and objects in those libraries can be referenced using regular library-qualified object name syntax. + * + * @param IASPGroup asp group name + * @param currentLib Current library which can be *CURSYSBAS, *CURUSR, *CRTDFT, name. If null or "" is set, + * default value *CURUSR is used. + * @param librariesForThread Libraries for current thread. If null is set, default value *CURUSR is used. Up to 250 + * libraries can be set. + * @throws AS400SecurityException If a security or authority error occurs. + * @throws ErrorCompletingRequestException If an error occurs before the request is completed. + * @throws IOException If an error occurs while communicating with the system. + * @throws InterruptedException If this thread is interrupted. + * @throws PropertyVetoException If the recipient wishes the property change to be rolled back. */ public void setIASPGroup(String IASPGroup, String currentLib, String[] librariesForThread) throws AS400SecurityException, ErrorCompletingRequestException, IOException, InterruptedException, PropertyVetoException { @@ -858,7 +887,7 @@ else if(librariesForThread.length>1) // Private constructor for use when a new object is needed and the password is already twiddled. // Used by password cache and password verification code. - private AS400(String systemName, String userId, CredentialVault pwVault, char[] additionalAuthenticationFactor) + private AS400(String systemName, String userId, CredentialVault pwVault, char[] additionalAuthFactor) { super(); if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Constructing internal AS400 object, system name: '" + systemName + "' user ID: '" + userId + "'"); @@ -894,18 +923,24 @@ private AS400(String systemName, String userId, CredentialVault pwVault, char[] // that behavior, but we need to do so using two different credential vaults, // because each AS400 object must always have its very own credential vault. credVault_ = pwVault.clone(); - setAdditionalAuthenticationFactor(additionalAuthenticationFactor); + setAdditionalAuthenticationFactor(additionalAuthFactor); proxyServer_ = resolveProxyServer(proxyServer_); } /** - Constructs an AS400 object. It uses the specified system name, user ID, and password. No sign-on prompt is displayed unless the sign-on fails. - @param systemName The name of the IBM i system. Use localhost to access data locally. - @param userId The user profile name to use to authenticate to the system. If running on IBM i, *CURRENT may be used to specify the current user ID. - @param password The user profile password to use to authenticate to the system. If running on IBM i, *CURRENT may be used to specify the current user ID. - @param proxyServer The name and port of the proxy server in the format serverName[:port]. If no port is specified, a default will be used. - @deprecated Use AS400((String systemName, String userId, char[] password, String proxyServer) instead. - **/ + * Constructs an AS400 object. It uses the specified system name, user ID, and password. No sign-on prompt is + * displayed unless the sign-on fails. + * + * @param systemName The name of the IBM i system. Use localhost to access data locally. + * @param userId The user profile name to use to authenticate to the system. If running on IBM i, *CURRENT may + * be used to specify the current user ID. + * @param password The user profile password to use to authenticate to the system. If running on IBM i, *CURRENT + * may be used to specify the current user ID. + * @param proxyServer The name and port of the proxy server in the format serverName[:port]. If no port + * is specified, a default will be used. + * @deprecated Use AS400((String systemName, String userId, char[] password, String proxyServer) instead. + **/ + @Deprecated public AS400(String systemName, String userId, String password, String proxyServer) { super(); @@ -948,12 +983,17 @@ public AS400(String systemName, String userId, String password, String proxyServ proxyServer_ = resolveProxyServer(proxyServer); } - /** - Constructs an AS400 object. It uses the specified system name, user ID, and password. No sign-on prompt is displayed unless the sign-on fails. - @param systemName The name of the IBM i system. Use localhost to access data locally. - @param userId The user profile name to use to authenticate to the system. If running on IBM i, *CURRENT may be used to specify the current user ID. - @param password The user profile password to use to authenticate to the system. The caller is responsible fore clearing sensitive data from password after the constructor runs. - @param proxyServer The name and port of the proxy server in the format serverName[:port]. If no port is specified, a default will be used. + /** + * Constructs an AS400 object. It uses the specified system name, user ID, and password. No sign-on prompt is + * displayed unless the sign-on fails. + * + * @param systemName The name of the IBM i system. Use localhost to access data locally. + * @param userId The user profile name to use to authenticate to the system. If running on IBM i, *CURRENT may + * be used to specify the current user ID. + * @param password The user profile password to use to authenticate to the system. The caller is responsible fore + * clearing sensitive data from password after the constructor runs. + * @param proxyServer The name and port of the proxy server in the format serverName[:port]. If no port + * is specified, a default will be used. **/ public AS400(String systemName, String userId, char[] password, String proxyServer) { @@ -989,8 +1029,10 @@ public AS400(String systemName, String userId, char[] password, String proxyServ /** - Constructs an AS400 object. It uses the same system name and user ID. This does not create a clone. The new object has the same behavior, but results in a new set of socket connections. - @param system A previously instantiated AS400 object. + * Constructs an AS400 object. It uses the same system name and user ID. This does not create a clone. The new + * object has the same behavior, but results in a new set of socket connections. + * + * @param system A previously instantiated AS400 object. **/ public AS400(AS400 system) { @@ -1030,9 +1072,9 @@ public AS400(AS400 system) showCheckboxes_ = system.showCheckboxes_; // If passed in system has SSL options, deep copy them if this instance is secure - if (system.isSecure()) { + if (system.isSecure()) useSSLConnection_= new SSLOptions(system.useSSLConnection_); - } + mustAddLanguageLibrary_ = system.mustAddLanguageLibrary_; mustUseSockets_ = system.mustUseSockets_; mustUseNetSockets_ = system.mustUseNetSockets_; @@ -1066,13 +1108,18 @@ public AS400(AS400 system) } /** - Returns a new instance of an AS400 object. It uses the specified system name. -

If running on IBM i to another system or to itself, the user ID and password of the current job are used. -

If running on another operating system, the user may be prompted for the user ID and password if a default - user has not been established for this system name. - @param useSSL Whether or not the new AS400 object should use secure connections when communicating with the host servers. - @param systemName The name of the IBM i system. Use localhost to access data locally. - **/ + * Returns a new instance of an AS400 object. It uses the specified system name. + *

+ * If running on IBM i to another system or to itself, the user ID and password of the current job are used. + *

+ * If running on another operating system, the user may be prompted for the user ID and password if a default user + * has not been established for this system name. + * + * @param useSSL Whether or not the new AS400 object should use secure connections when communicating with the + * host servers. + * @param systemName The name of the IBM i system. Use localhost to access data locally. + * @return AS400 object. + **/ public static AS400 newInstance(boolean useSSL, String systemName) { return (useSSL) ? new SecureAS400(systemName) @@ -1080,12 +1127,19 @@ public static AS400 newInstance(boolean useSSL, String systemName) } /** - Returns a new instance of an AS400 object. It uses the specified system name, and user ID. When the sign-on prompt is displayed, - the user is able to specify the password. Note that the user ID may be overridden in the AS400 object. - @param useSSL Whether or not the new AS400 object should use secure connections when communicating with the host servers. - @param systemName The name of the IBM i system. Use localhost to access data locally. - @param userId The user profile name to use to authenticate to the system. If running on IBM i, *CURRENT may be used to specify the current user ID. - **/ + * Returns a new instance of an AS400 object. It uses the specified system name, and user ID. When the sign-on + * prompt is displayed, the user is able to specify the password. Note that the user ID may be overridden in the + * AS400 object. + * + * @param useSSL Whether or not the new AS400 object should use secure connections when communicating with the + * host servers. + * @param systemName The name of the IBM i system. Use localhost to access data locally. + * @param userId The user profile name to use to authenticate to the system. If running on IBM i, *CURRENT may + * be used to specify the current user ID. + * @return AS400 object. + * @throws IOException If an error occurs while communicating with the system. + * @throws AS400SecurityException If a security or authority error occurs. + **/ public static AS400 newInstance(boolean useSSL, String systemName, String userId) throws IOException, AS400SecurityException { return (useSSL) ? new SecureAS400(systemName, userId) @@ -1093,30 +1147,43 @@ public static AS400 newInstance(boolean useSSL, String systemName, String userId } /** - Returns a new instance of an AS400 object. It uses the specified system name, user ID, password, and additional authentication - factor. No sign-on prompt is displayed unless the sign-on fails. - @param useSSL Whether or not the new AS400 object should use secure connections when communicating with the host servers. - @param systemName The name of the IBM i system. Use localhost to access data locally. - @param userId The user profile name to use to authenticate to the system. If running on IBM i, *CURRENT may be used to specify the current user ID. - @param password The user profile password to use to authenticate to the system. - The caller is responsible for clearing the password array to keep the password from residing in memory. - @param additionalAuthenticationFactor Additional authentication factor (or null if not providing one). - **/ - public static AS400 newInstance(boolean useSSL, String systemName, String userId, char[] password, char[] additionalAuthenticationFactor) throws IOException, AS400SecurityException - { - return (useSSL) ? new SecureAS400(systemName, userId, password, additionalAuthenticationFactor) - : new AS400(systemName, userId, password, additionalAuthenticationFactor); + * Returns a new instance of an AS400 object. It uses the specified system name, user ID, password, and additional + * authentication factor. No sign-on prompt is displayed unless the sign-on fails. + * + * @param useSSL Whether or not the new AS400 object should use secure connections when communicating + * with the host servers. + * @param systemName The name of the IBM i system. Use localhost to access data locally. + * @param userId The user profile name to use to authenticate to the system. If running on IBM i, + * *CURRENT may be used to specify the current user ID. + * @param password The user profile password to use to authenticate to the system. The caller is + * responsible for clearing the password array to keep the password from residing in + * memory. + * @param additionalAuthFactor Additional authentication factor (or null if not providing one). + * @return AS400 object. + * @throws IOException If an error occurs while communicating with the system. + * @throws AS400SecurityException If a security or authority error occurs. + **/ + public static AS400 newInstance(boolean useSSL, String systemName, String userId, char[] password, char[] additionalAuthFactor) throws IOException, AS400SecurityException + { + return (useSSL) ? new SecureAS400(systemName, userId, password, additionalAuthFactor) + : new AS400(systemName, userId, password, additionalAuthFactor); } /** - Returns a new instance of an AS400 object. It uses the specified system name, user ID, and password. - No sign-on prompt is displayed unless the sign-on fails. - @param useSSL Whether or not the new AS400 object should use secure connections when communicating with the host servers. - @param systemName The name of the IBM i system. Use localhost to access data locally. - @param userId The user profile name to use to authenticate to the system. If running on IBM i, *CURRENT may be used to specify the current user ID. - @param password The user profile password to use to authenticate to the system. The caller is responsible fore clearing sensitive data from password after the constructor runs. - @param proxyServer The name and port of the proxy server in the format serverName[:port]. If no port is specified, a default will be used. - **/ + * Returns a new instance of an AS400 object. It uses the specified system name, user ID, and password. No sign-on + * prompt is displayed unless the sign-on fails. + * + * @param useSSL Whether or not the new AS400 object should use secure connections when communicating with the + * host servers. + * @param systemName The name of the IBM i system. Use localhost to access data locally. + * @param userId The user profile name to use to authenticate to the system. If running on IBM i, *CURRENT may + * be used to specify the current user ID. + * @param password The user profile password to use to authenticate to the system. The caller is responsible fore + * clearing sensitive data from password after the constructor runs. + * @param proxyServer The name and port of the proxy server in the format serverName[:port]. If no port + * is specified, a default will be used. + * @return AS400 object. + **/ public static AS400 newInstance(boolean useSSL, String systemName, String userId, char[] password, String proxyServer) { return (useSSL) ? new SecureAS400(systemName, userId, password, proxyServer) @@ -1124,11 +1191,14 @@ public static AS400 newInstance(boolean useSSL, String systemName, String userId } /** - Returns a new instance of an AS400 object. It uses the specified system name and profile token. - @param useSSL Whether or not the new AS400 object should use secure connections when communicating with the host servers. - @param systemName The name of the IBM i system. Use localhost to access data locally. - @param profileToken The profile token to use to authenticate to the system. - **/ + * Returns a new instance of an AS400 object. It uses the specified system name and profile token. + * + * @param useSSL Whether or not the new AS400 object should use secure connections when communicating with the + * host servers. + * @param systemName The name of the IBM i system. Use localhost to access data locally. + * @param profileToken The profile token to use to authenticate to the system. + * @return AS400 object. + **/ public static AS400 newInstance(boolean useSSL, String systemName, ProfileTokenCredential profileToken) { return (useSSL) ? new SecureAS400(systemName, profileToken) @@ -1136,11 +1206,14 @@ public static AS400 newInstance(boolean useSSL, String systemName, ProfileTokenC } /** - Returns a new instance of an AS400 object. It uses the same system name and user ID. This does not create a clone. - The new object has the same behavior, but results in a new set of socket connections. - @param useSSL Whether or not the new AS400 object should use secure connections when communicating with the host server. - @param system A previously instantiated AS400 object. - **/ + * Returns a new instance of an AS400 object. It uses the same system name and user ID. This does not create a + * clone. The new object has the same behavior, but results in a new set of socket connections. + * + * @param useSSL Whether or not the new AS400 object should use secure connections when communicating with the host + * server. + * @param system A previously instantiated AS400 object. + * @return AS400 object. + **/ public static AS400 newInstance(boolean useSSL, AS400 system) { return (useSSL) ? new SecureAS400(system) @@ -1148,8 +1221,9 @@ public static AS400 newInstance(boolean useSSL, AS400 system) } /** - Adds a listener to be notified when a connection event occurs. - @param listener The listener object. + * Adds a listener to be notified when a connection event occurs. + * + * @param listener The listener object. **/ public void addConnectionListener(ConnectionListener listener) { @@ -1185,26 +1259,28 @@ public void disconnected(ConnectionEvent event) { } /** - Validates the user ID and password, and if successful, adds the information to the password cache. - @param systemName The name of the IBM i system. - @param userId The user profile name. - @param password The user profile password. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. - @deprecated Use addPasswordCacheEntry(String systemName, String userId, char[] password) instead + * Validates the user ID and password, and if successful, adds the information to the password cache. + * + * @param systemName The name of the IBM i system. + * @param userId The user profile name. + * @param password The user profile password. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. + * @deprecated Use addPasswordCacheEntry(String systemName, String userId, char[] password) instead **/ public static void addPasswordCacheEntry(String systemName, String userId, String password) throws AS400SecurityException, IOException { addPasswordCacheEntry(systemName, userId, (password == null) ? (char[])null : password.toCharArray(), false); } - /** - Validates the user ID and password, and if successful, adds the information to the password cache. - @param systemName The name of the IBM i system. - @param userId The user profile name. - @param password The user profile password. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. + /** + * Validates the user ID and password, and if successful, adds the information to the password cache. + * + * @param systemName The name of the IBM i system. + * @param userId The user profile name. + * @param password The user profile password. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. **/ public static void addPasswordCacheEntry(String systemName, String userId, char[] password) throws AS400SecurityException, IOException { @@ -1212,14 +1288,15 @@ public static void addPasswordCacheEntry(String systemName, String userId, char[ } /** - Validates the user ID and password, and if successful, adds the information to the password cache. - @param systemName The name of the IBM i system. - @param userId The user profile name. - @param password The user profile password. - @param useSSL Whether or not secure connections should be used when communicating with the host servers. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. - **/ + * Validates the user ID and password, and if successful, adds the information to the password cache. + * + * @param systemName The name of the IBM i system. + * @param userId The user profile name. + * @param password The user profile password. + * @param useSSL Whether or not secure connections should be used when communicating with the host servers. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. + **/ public static void addPasswordCacheEntry(String systemName, String userId, char[] password, boolean useSSL) throws AS400SecurityException, IOException { if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Adding password cache entry, system name: '" + systemName + "' user ID: '" + userId + "'" + " useSSL: " + useSSL); @@ -1227,44 +1304,52 @@ public static void addPasswordCacheEntry(String systemName, String userId, char[ } /** - Validates the user ID and password, and if successful, adds the information to the password cache. - @param systemName The name of the IBM i system. - @param userId The user profile name. - @param password The user profile password. - @param proxyServer The name and port of the proxy server in the format serverName[:port]. If no port is specified, a default will be used. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. - @deprecated Use addPasswordCacheEntry(String systemName, String userId, char[] password, String proxyServer) instead. - **/ + * Validates the user ID and password, and if successful, adds the information to the password cache. + * + * @param systemName The name of the IBM i system. + * @param userId The user profile name. + * @param password The user profile password. + * @param proxyServer The name and port of the proxy server in the format serverName[:port]. If no port + * is specified, a default will be used. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. + * @deprecated Use addPasswordCacheEntry(String systemName, String userId, char[] password, String proxyServer) + * instead. + **/ + @Deprecated public static void addPasswordCacheEntry(String systemName, String userId, String password, String proxyServer) throws AS400SecurityException, IOException { addPasswordCacheEntry(systemName, userId, (password == null) ? (char[])null : password.toCharArray(), proxyServer, false); } /** - Validates the user ID and password, and if successful, adds the information to the password cache. - @param systemName The name of the IBM i system. - @param userId The user profile name. - @param password The user profile password. - @param proxyServer The name and port of the proxy server in the format serverName[:port]. If no port is specified, a default will be used. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. - **/ + * Validates the user ID and password, and if successful, adds the information to the password cache. + * + * @param systemName The name of the IBM i system. + * @param userId The user profile name. + * @param password The user profile password. + * @param proxyServer The name and port of the proxy server in the format serverName[:port]. If no port + * is specified, a default will be used. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. + **/ public static void addPasswordCacheEntry(String systemName, String userId, char[] password, String proxyServer) throws AS400SecurityException, IOException { addPasswordCacheEntry(systemName, userId, password, proxyServer, false); } - /** - Validates the user ID and password, and if successful, adds the information to the password cache. - @param systemName The name of the IBM i system. - @param userId The user profile name. - @param password The user profile password. - @param proxyServer The name and port of the proxy server in the format serverName[:port]. If no port is specified, a default will be used. - @param useSSL Whether or not secure connections should be used when communicating with the host servers. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. - **/ + /** + * Validates the user ID and password, and if successful, adds the information to the password cache. + * + * @param systemName The name of the IBM i system. + * @param userId The user profile name. + * @param password The user profile password. + * @param proxyServer The name and port of the proxy server in the format serverName[:port]. If no port + * is specified, a default will be used. + * @param useSSL Whether or not secure connections should be used when communicating with the host servers. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. + **/ public static void addPasswordCacheEntry(String systemName, String userId, char[] password, String proxyServer, boolean useSSL) throws AS400SecurityException, IOException { if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Adding password cache entry, system name: '" + systemName + "' user ID: '" + userId + "' proxy server: '" + proxyServer + "'" + "' useSSL: '" + useSSL); @@ -1278,8 +1363,9 @@ private static void addPasswordCacheEntry(AS400 system) throws AS400SecurityExce } /** - Adds a listener to be notified when the value of any property is changed. - @param listener The listener object. + * Adds a listener to be notified when the value of any property is changed. + * + * @param listener The listener object. **/ public void addPropertyChangeListener(PropertyChangeListener listener) { @@ -1298,8 +1384,10 @@ public void addPropertyChangeListener(PropertyChangeListener listener) } /** - Adds a listener to be notified when the value of any constrained property is changed. The vetoableChange method will be called. - @param listener The listener object. + * Adds a listener to be notified when the value of any constrained property is changed. The vetoableChange method + * will be called. + * + * @param listener The listener object. **/ public void addVetoableChangeListener(VetoableChangeListener listener) { @@ -1318,8 +1406,11 @@ public void addVetoableChangeListener(VetoableChangeListener listener) } /** - Indicates if properties are frozen. If this is true, property changes should not be made. Properties are not the same thing as attributes. Properties are basic pieces of information which must be set to make the object usable, such as the system name, user ID or other properties that identify the resource. - @return true if properties are frozen, false otherwise. + * Indicates if properties are frozen. If this is true, property changes should not be made. Properties are not the + * same thing as attributes. Properties are basic pieces of information which must be set to make the object usable, + * such as the system name, user ID or other properties that identify the resource. + * + * @return true if properties are frozen, false otherwise. **/ public boolean arePropertiesFrozen() { @@ -1328,25 +1419,26 @@ public boolean arePropertiesFrozen() } /** - Checks whether an additional authentication factor is accepted for the given system. - The communications with the host server is done over a secure channel if the AS400 object - was created to use SSL; otherwise, the communications with the host server is done over - an unsecure channel. - @return whether the server accepts the additional authentication factor - @exception IOException If an error occurs while communicating with the system. - @throws AS400SecurityException If an error occurs exchanging client/server information - **/ + * Checks whether an additional authentication factor is accepted for the given system. The communications with the + * host server is done over a secure channel if the AS400 object was created to use SSL; otherwise, the + * communications with the host server is done over an unsecure channel. + * + * @return whether the server accepts the additional authentication factor + * @exception IOException If an error occurs while communicating with the system. + * @throws AS400SecurityException If an error occurs exchanging client/server information + **/ public boolean isAdditionalAuthenticationFactorAccepted() throws IOException, AS400SecurityException { return isAdditionalAuthenticationFactorAccepted(getSystemName(), isSecure()); } /** - Checks whether an additional authentication factor is accepted for the given system - @param systemName The IP address or hostname of the target system - @param useSSL Whether or not secure connections should be used when communicating with the host servers. - @return whether the server accepts the additional authentication factor - @exception IOException If an error occurs while communicating with the system. - @throws AS400SecurityException If an error occurs exchanging client/server information + * Checks whether an additional authentication factor is accepted for the given system + * + * @param systemName The IP address or hostname of the target system + * @param useSSL Whether or not secure connections should be used when communicating with the host servers. + * @return whether the server accepts the additional authentication factor + * @exception IOException If an error occurs while communicating with the system. + * @throws AS400SecurityException If an error occurs exchanging client/server information **/ public static boolean isAdditionalAuthenticationFactorAccepted(String systemName, boolean useSSL) throws IOException, AS400SecurityException { if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Getting whether additional factor accepted: " + systemName + ", use SSL:", useSSL); @@ -1354,31 +1446,38 @@ public static boolean isAdditionalAuthenticationFactorAccepted(String systemNam } /** - Checks whether an additional authentication factor is accepted for the given system - @param systemName The IP address or hostname of the target system - @return whether the server accepts the additional authentication factor - @exception IOException If an error occurs while communicating with the system. - @throws AS400SecurityException If an error occurs exchanging client/server information - @deprecated Use {@link #isAdditionalAuthenticationFactorAccepted(String, boolean)} - **/ + * Checks whether an additional authentication factor is accepted for the given system + * + * @param systemName The IP address or hostname of the target system + * @return whether the server accepts the additional authentication factor + * @exception IOException If an error occurs while communicating with the system. + * @throws AS400SecurityException If an error occurs exchanging client/server information + * @deprecated Use {@link #isAdditionalAuthenticationFactorAccepted(String, boolean)} + **/ + @Deprecated public static boolean isAdditionalAuthenticationFactorAccepted(String systemName) throws IOException, AS400SecurityException { return isAdditionalAuthenticationFactorAccepted(systemName, false); } /** - Authenticate the user ID and password on the system and adds to the signon-list. This means that authentication - is performed using the AS400 object instance for which this method is invoked - a new AS400 object is not created to do - the authentication (unlike the other authenticate(String, String) or validateSignon() methods). -

If the AS400 object has previously - been authenticated, either by using authenticate() or indirectly such as when establishing a connection to a host server, and - if any of the setter methods are used after the authentication to change credentials, such as user ID or system name, - the AS400.HOSTCNN and/or AS400.SIGNON server connections, if they exist, may be discarded if the change is different than what - was previously used in the authentication process. -

Note: This will return true if the information is successfully validated. An unsuccessful validation will cause an exception to be thrown, false is never returned. -

Note:If an additional authentication factor has been set in the AS400 object, it is used. - @return true if successful. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. + * Authenticate the user ID and password on the system and adds to the signon-list. This means that authentication + * is performed using the AS400 object instance for which this method is invoked - a new AS400 object is not created + * to do the authentication (unlike the other authenticate(String, String) or validateSignon() methods). + *

+ * If the AS400 object has previously been authenticated, either by using authenticate() or indirectly such as when + * establishing a connection to a host server, and if any of the setter methods are used after the authentication to + * change credentials, such as user ID or system name, the AS400.HOSTCNN and/or AS400.SIGNON server connections, if + * they exist, may be discarded if the change is different than what was previously used in the authentication + * process. + *

+ * Note: This will return true if the information is successfully validated. An unsuccessful validation will + * cause an exception to be thrown, false is never returned. + *

+ * Note:If an additional authentication factor has been set in the AS400 object, it is used. + * + * @return true if successful. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. **/ public boolean authenticate() throws AS400SecurityException, IOException { @@ -1401,19 +1500,28 @@ public boolean authenticate() throws AS400SecurityException, IOException } /** - Authenticates the user profile name and user profile password. -

This method is functionally equivalent to the validateSignon() method, except it does not alter the user profile assigned to this object, - impact the status of existing connections, or otherwise impact the user and authorities on which the application is running. -

The system name needs to be set prior to calling this method. -

Note: Providing an incorrect password increments the number of failed sign-on attempts for the user profile, and can result in the profile being disabled. -

Note: This will return true if the information is successfully validated. An unsuccessful validation will cause an exception to be thrown, false is never returned. - @param userId The user profile name. - @param password The user profile password. - @return true if successful. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. - @deprecated Using a String as a password is insecure. - **/ + * Authenticates the user profile name and user profile password. + *

+ * This method is functionally equivalent to the validateSignon() method, except it does not alter the user + * profile assigned to this object, impact the status of existing connections, or otherwise impact the user and + * authorities on which the application is running. + *

+ * The system name needs to be set prior to calling this method. + *

+ * Note: Providing an incorrect password increments the number of failed sign-on attempts for the user + * profile, and can result in the profile being disabled. + *

+ * Note: This will return true if the information is successfully validated. An unsuccessful validation will + * cause an exception to be thrown, false is never returned. + * + * @param userId The user profile name. + * @param password The user profile password. + * @return true if successful. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. + * @deprecated Using a String as a password is insecure. + **/ + @Deprecated public boolean authenticate(String userId, String password) throws AS400SecurityException, IOException { if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Authenticating signon information:", userId); @@ -1421,18 +1529,26 @@ public boolean authenticate(String userId, String password) throws AS400Security } - /** - Authenticates the user profile name and user profile password. -

This method is functionally equivalent to the validateSignon() method, except it does not alter the user profile assigned to this object, - impact the status of existing connections, or otherwise impact the user and authorities on which the application is running. -

The system name needs to be set prior to calling this method. -

Note: Providing an incorrect password increments the number of failed sign-on attempts for the user profile, and can result in the profile being disabled. -

Note: This will return true if the information is successfully validated. An unsuccessful validation will cause an exception to be thrown, false is never returned. - @param userId The user profile name. - @param password The user profile password. - @return true if successful. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. + /** + * Authenticates the user profile name and user profile password. + *

+ * This method is functionally equivalent to the validateSignon() method, except it does not alter the user + * profile assigned to this object, impact the status of existing connections, or otherwise impact the user and + * authorities on which the application is running. + *

+ * The system name needs to be set prior to calling this method. + *

+ * Note: Providing an incorrect password increments the number of failed sign-on attempts for the user + * profile, and can result in the profile being disabled. + *

+ * Note: This will return true if the information is successfully validated. An unsuccessful validation will + * cause an exception to be thrown, false is never returned. + * + * @param userId The user profile name. + * @param password The user profile password. + * @return true if successful. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. **/ public boolean authenticate(String userId, char[] password) throws AS400SecurityException, IOException { @@ -1463,12 +1579,15 @@ private static int getNativeVersion() } /** - Indicates if this AS400 object is enabled to exploit Toolbox native optimizations. This requires that the native optimization classes are available on the classpath, and this AS400 object represents the local system and is configured to allow the native optimizations to be used. - Note: If the authentication scheme is other than {@link #AUTHENTICATION_SCHEME_PASSWORD AUTHENTICATION_SCHEME_PASSWORD}, native optimizations will not be used. - @return true if the native optimizations can be used; false otherwise. - @see #isLocal - @see #isMustUseSockets - @see #getAuthenticationScheme + * Indicates if this AS400 object is enabled to exploit Toolbox native optimizations. This requires that the native + * optimization classes are available on the classpath, and this AS400 object represents the local system and is + * configured to allow the native optimizations to be used. Note: If the authentication scheme is other than + * {@link #AUTHENTICATION_SCHEME_PASSWORD AUTHENTICATION_SCHEME_PASSWORD}, native optimizations will not be used. + * + * @return true if the native optimizations can be used; false otherwise. + * @see #isLocal + * @see #isMustUseSockets + * @see #getAuthenticationScheme **/ public boolean canUseNativeOptimizations() { @@ -1528,13 +1647,16 @@ private static final String credTypeToString(int credType) } /** - Changes the user profile password. The system name and user profile name need to be set prior to calling this method. - @param oldPassword The old user profile password. - @param newPassword The new user profile password. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. - @deprecated Use changePassword(char[] oldPassword, char[] newPassword) instead + * Changes the user profile password. The system name and user profile name need to be set prior to calling this + * method. + * + * @param oldPassword The old user profile password. + * @param newPassword The new user profile password. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. + * @deprecated Use changePassword(char[] oldPassword, char[] newPassword) instead **/ + @Deprecated public void changePassword(String oldPassword, String newPassword) throws AS400SecurityException, IOException { char[] oldPasswordChars = (oldPassword == null) ? null : oldPassword.toCharArray(); @@ -1550,12 +1672,14 @@ public void changePassword(String oldPassword, String newPassword) throws AS400S } - /** - Changes the user profile password. The system name and user profile name need to be set prior to calling this method. - @param oldPassword The old user profile password. - @param newPassword The new user profile password. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. + /** + * Changes the user profile password. The system name and user profile name need to be set prior to calling this + * method. + * + * @param oldPassword The old user profile password. + * @param newPassword The new user profile password. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. **/ public void changePassword(char[] oldPassword, char[] newPassword) throws AS400SecurityException, IOException { @@ -1563,15 +1687,17 @@ public void changePassword(char[] oldPassword, char[] newPassword) throws AS400S } - /** - Changes the user profile password. The system name and user profile name need to be set prior to calling this method. - @param oldPassword The old user profile password. - @param newPassword The new user profile password. - @param additionalAuthenticationFactor Additional authentication factor (or null if not providing one). - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. + /** + * Changes the user profile password. The system name and user profile name need to be set prior to calling this + * method. + * + * @param oldPassword The old user profile password. + * @param newPassword The new user profile password. + * @param additionalAuthFactor Additional authentication factor (or null if not providing one). + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. **/ - public void changePassword(char[] oldPassword, char[] newPassword, char[] additionalAuthenticationFactor) throws AS400SecurityException, IOException + public void changePassword(char[] oldPassword, char[] newPassword, char[] additionalAuthFactor) throws AS400SecurityException, IOException { if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Changing password."); if (PASSWORD_TRACE) @@ -1628,7 +1754,7 @@ public void changePassword(char[] oldPassword, char[] newPassword, char[] additi byte[] encodeNewBytes = CredentialVault.encode(proxySeed, remoteSeed, newbytes); signonInfo_ = impl_.changePassword(systemName_, systemNameLocal_, userId_, - encodeOldBytes, encodeNewBytes, additionalAuthenticationFactor); + encodeOldBytes, encodeNewBytes, additionalAuthFactor); } finally { CredentialVault.clearArray(oldbytes); @@ -1674,7 +1800,7 @@ private synchronized void chooseImpl() } /** - Clears the password cache for all systems within this Java virtual machine. + * Clears the password cache for all systems within this Java virtual machine. **/ public static void clearPasswordCache() { @@ -1686,8 +1812,9 @@ public static void clearPasswordCache() } /** - Clears all the passwords that are cached for the given system name within this Java virtual machine. - @param systemName The name of the IBM i system. + * Clears all the passwords that are cached for the given system name within this Java virtual machine. + * + * @param systemName The name of the IBM i system. **/ public static void clearPasswordCache(String systemName) { @@ -1729,45 +1856,50 @@ else if ((longName != null) && longName.equalsIgnoreCase(elementName)) } /** - Connects to a service. Security is validated and a connection is established. -

Services typically connect implicitly; therefore, this method does not have to be called to use a service. This method can be used to control when the connection is established. - @param service The name of the service. Valid services are: -

- @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. - **/ + * Connects to a service. Security is validated and a connection is established. + *

+ * Services typically connect implicitly; therefore, this method does not have to be called to use a service. This + * method can be used to control when the connection is established. + * + * @param service The name of the service. Valid services are: + *

+ * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. + **/ public void connectService(int service) throws AS400SecurityException, IOException { connectService(service, -1); } - /** - Connects to a service. Security is validated and a connection is established. -

Services typically connect implicitly; therefore, this method does not have to be called to use a service. This method can be used to control when the connection is established. - @param service The name of the service. Valid services are: -

- @param overridePort If non-negative, used to override the port to be - used for the connection. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. - **/ + /** + * Connects to a service. Security is validated and a connection is established. + *

+ * Services typically connect implicitly; therefore, this method does not have to be called to use a service. This + * method can be used to control when the connection is established. + * + * @param service The name of the service. Valid services are: + *

+ * @param overridePort If non-negative, used to override the port to be used for the connection. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. + **/ public void connectService(int service, int overridePort) throws AS400SecurityException, IOException { if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Connecting service:", service); @@ -1802,11 +1934,12 @@ public void connectService(int service, int overridePort) throws AS400SecurityEx } /** - Connects to a port on the server, via DHCP. Security is validated and a connection is established. - @param port The port number to connect to. - @return A Socket object representing the connection. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. + * Connects to a port on the server, via DHCP. Security is validated and a connection is established. + * + * @param port The port number to connect to. + * @return A Socket object representing the connection. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. **/ public Socket connectToPort(int port) throws AS400SecurityException, IOException { @@ -1820,13 +1953,14 @@ public Socket connectToPort(int port) throws AS400SecurityException, IOException } /** - Connects to a port on the server, via DHCP. Security is validated and a connection is established. - @param port The port number to connect to. - @param forceNonLocalhost whether to use localhost when connect to the port if running on as400 - @return A Socket object representing the connection. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. - **/ + * Connects to a port on the server, via DHCP. Security is validated and a connection is established. + * + * @param port The port number to connect to. + * @param forceNonLocalhost whether to use localhost when connect to the port if running on as400 + * @return A Socket object representing the connection. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. + **/ // Add this interface for L1C for the issue of DHCP server has listened on 942 for STRTCPSVR on localhost. public Socket connectToPort(int port,boolean forceNonLocalhost) throws AS400SecurityException, IOException { @@ -1865,9 +1999,10 @@ private void construct() } /** - Disconnects all services. All socket connections associated with this object will be closed. - The signon information is not changed, and connection properties remain frozen. - @see #resetAllServices + * Disconnects all services. All socket connections associated with this object will be closed. The signon + * information is not changed, and connection properties remain frozen. + * + * @see #resetAllServices **/ public void disconnectAllServices() { @@ -1889,19 +2024,20 @@ public void disconnectAllServices() } /** - Disconnects the service. All socket connections associated with this service and this object will be closed. - @param service The name of the service. Valid services are: - + * Disconnects the service. All socket connections associated with this service and this object will be closed. + * + * @param service The name of the service. Valid services are: + * **/ public void disconnectService(int service) { @@ -1933,21 +2069,30 @@ private void fireConnectEvent(ConnectionEvent event, boolean connect) } /** - Generates a profile token on behalf of the provided user identity. This user identity must be associated with a user profile via EIM. -

Invoking this method does not change the user ID and password assigned to the system or otherwise modify the user or authorities under which the application is running. - The profile associated with this system object must have enough authority to generate an authentication token for another user. -

This function is only supported on i5/OS V5R3M0 or greater. - @param userIdentity The LDAP distinguished name. - @param tokenType The type of profile token to create. Possible types are defined as fields on the ProfileTokenCredential class: -

- @param timeoutInterval The number of seconds to expiration when the token is created (1-3600). - @return A ProfileTokenCredential representing the provided user identity. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. + * Generates a profile token on behalf of the provided user identity. This user identity must be associated with a + * user profile via EIM. + *

+ * Invoking this method does not change the user ID and password assigned to the system or otherwise modify the user + * or authorities under which the application is running. The profile associated with this system object must have + * enough authority to generate an authentication token for another user. + *

+ * This function is only supported on i5/OS V5R3M0 or greater. + * + * @param userIdentity The LDAP distinguished name. + * @param tokenType The type of profile token to create. Possible types are defined as fields on the + * ProfileTokenCredential class: + *

+ * @param timeoutInterval The number of seconds to expiration when the token is created (1-3600). + * @return A ProfileTokenCredential representing the provided user identity. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. **/ public ProfileTokenCredential generateProfileToken(String userIdentity, int tokenType, int timeoutInterval) throws AS400SecurityException, IOException { @@ -1978,11 +2123,13 @@ public ProfileTokenCredential generateProfileToken(String userIdentity, int toke } /** - Generates a VRM from a version, release, and modification. This can then be used to compare against the VRM returned by getVRM(). - @param version The version. - @param release The release. - @param modification The modification level. - @return The generated VRM. + * Generates a VRM from a version, release, and modification. This can then be used to compare against the VRM + * returned by getVRM(). + * + * @param version The version. + * @param release The release. + * @param modification The modification level. + * @return The generated VRM. **/ public static int generateVRM(int version, int release, int modification) { @@ -2000,14 +2147,17 @@ public static int generateVRM(int version, int release, int modification) } /** - Returns the authentication scheme for this object. By default this object starts in password mode. This value may not be correct before a connection to the system has been made. Valid authentication schemes are: - - @return The authentication scheme in use for this object. + * Returns the authentication scheme for this object. By default this object starts in password mode. This value may + * not be correct before a connection to the system has been made. Valid authentication schemes are: + * + * + * @return The authentication scheme in use for this object. **/ public int getAuthenticationScheme() { @@ -2016,8 +2166,10 @@ public int getAuthenticationScheme() } /** - Returns the CCSID for this object. The CCSID returned either is the one retrieved based on the user profile or is set by the setCcsid() method. - @return The CCSID in use for this object. + * Returns the CCSID for this object. The CCSID returned either is the one retrieved based on the user profile or is + * set by the setCcsid() method. + * + * @return The CCSID in use for this object. **/ public int getCcsid() { @@ -2065,11 +2217,13 @@ private int getDaysToExpiration() return 365; } - /** - Returns the default sign-on handler. If none has been specified, returns an instance of the Toolbox's internal sign-on handler. - @return The default sign-on handler. Never returns null. - @see #setDefaultSignonHandler - **/ + /** + * Returns the default sign-on handler. If none has been specified, returns an instance of the Toolbox's internal + * sign-on handler. + * + * @return The default sign-on handler. Never returns null. + * @see #setDefaultSignonHandler + **/ public static SignonHandler getDefaultSignonHandler() { if (defaultSignonHandler_ != null) return defaultSignonHandler_; @@ -2084,9 +2238,12 @@ public static SignonHandler getDefaultSignonHandler() } /** - Returns the relational database name (RDB name) used for record-level access (DDM) connections. The RDB name corresponds to the independent auxiliary storage pool (IASP) that is being used. - @return The name of the IASP or RDB that is in use by this object's RECORDACCESS service, or null if the IASP used will be the default system pool (*SYSBAS). - @see #setDDMRDB + * Returns the relational database name (RDB name) used for record-level access (DDM) connections. The RDB name + * corresponds to the independent auxiliary storage pool (IASP) that is being used. + * + * @return The name of the IASP or RDB that is in use by this object's RECORDACCESS service, or null if the IASP + * used will be the default system pool (*SYSBAS). + * @see #setDDMRDB **/ public String getDDMRDB() { @@ -2094,9 +2251,11 @@ public String getDDMRDB() } /** - Returns the default user ID for this system name. This user ID is used to connect if a user ID was not used to construct the object. - @param systemName The name of the IBM i system. - @return The default user ID for this system. A null is returned if there is not a default user. + * Returns the default user ID for this system name. This user ID is used to connect if a user ID was not used to + * construct the object. + * + * @param systemName The name of the IBM i system. + * @return The default user ID for this system. A null is returned if there is not a default user. **/ public static String getDefaultUser(String systemName) { @@ -2110,8 +2269,9 @@ public static String getDefaultUser(String systemName) } /** - Returns the GSS name string. This method will only return the information provided on the setGSSName() method. - @return The GSS name string, or an empty string ("") if not set. + * Returns the GSS name string. This method will only return the information provided on the setGSSName() method. + * + * @return The GSS name string, or an empty string ("") if not set. **/ public synchronized String getGSSName() { @@ -2120,13 +2280,14 @@ public synchronized String getGSSName() } /** - Returns the option for how the JGSS framework will be used. - @return A constant indicating how the JGSS framework will be used. Valid values are: - + * Returns the option for how the JGSS framework will be used. + * + * @return A constant indicating how the JGSS framework will be used. Valid values are: + * **/ public int getGSSOption() { @@ -2134,8 +2295,9 @@ public int getGSSOption() return gssOption_; } - /** Get underlying AS400Impl object. - * Should only be used by code internal to the driver. + /** + * Get underlying AS400Impl object. Should only be used by code internal to the driver. + * * @return underlying AS400Impl object */ public AS400Impl getImpl() @@ -2155,11 +2317,12 @@ int getJobCcsid() throws AS400SecurityException, IOException } /** - Returns the encoding that corresponds to the job CCSID. - @return The encoding. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. - @exception InterruptedException If this thread is interrupted. + * Returns the encoding that corresponds to the job CCSID. + * + * @return The encoding. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. + * @exception InterruptedException If this thread is interrupted. **/ public String getJobCCSIDEncoding() throws AS400SecurityException, IOException, InterruptedException { @@ -2175,21 +2338,23 @@ public String getJobCCSIDEncoding() throws AS400SecurityException, IOException, } /** - Returns an array of Job objects representing the jobs to which this object is connected. This information - is only available when connecting to i5/OS V5R2M0 and later systems. The array will be of length zero if no connections are currently active. - @param service The name of the service. Valid services are: - - @return The array of job objects. + * Returns an array of Job objects representing the jobs to which this object is connected. This information is only + * available when connecting to i5/OS V5R2M0 and later systems. The array will be of length zero if no connections + * are currently active. + * + * @param service The name of the service. Valid services are: + * + * @return The array of job objects. **/ public Job[] getJobs(int service) { @@ -2220,8 +2385,12 @@ public Job[] getJobs(int service) } /** - Returns the Locale associated with this system object. The Locale may have been set with the setLocale() method, or it may be the default Locale for the client environment. Unless specifically overridden, this Locale is used to set the National Language Version (NLV) on the system. Only the COMMAND, PRINT, and DATABASE services accept an NLV. - @return The Locale object. + * Returns the Locale associated with this system object. The Locale may have been set with the setLocale() method, + * or it may be the default Locale for the client environment. Unless specifically overridden, this Locale is used + * to set the National Language Version (NLV) on the system. Only the COMMAND, PRINT, and DATABASE services accept + * an NLV. + * + * @return The Locale object. **/ public Locale getLocale() { @@ -2230,11 +2399,14 @@ public Locale getLocale() } /** - Returns the modification level of the IBM i system. -

A connection is required to the system to retrieve this information. If a connection has not been established, one is created to retrieve the information. - @return The modification level. For example, version 5, release 1, modification level 0 returns 0. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. + * Returns the modification level of the IBM i system. + *

+ * A connection is required to the system to retrieve this information. If a connection has not been established, + * one is created to retrieve the information. + * + * @return The modification level. For example, version 5, release 1, modification level 0 returns 0. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. **/ public int getModification() throws AS400SecurityException, IOException { @@ -2250,8 +2422,10 @@ public int getModification() throws AS400SecurityException, IOException } /** - Returns the National Language Version (NLV) that will be sent to the system. Only the COMMAND, PRINT, and DATABASE services accept an NLV. - @return The NLV. + * Returns the National Language Version (NLV) that will be sent to the system. Only the COMMAND, PRINT, and + * DATABASE services accept an NLV. + * + * @return The NLV. **/ public String getNLV() { @@ -2260,11 +2434,15 @@ public String getNLV() } /** - Returns the password expiration date for the signed-on user. If the profile's password expiration interval is set to *NOMAX, null is returned. -

A connection is required to retrieve this information. If a connection has not been established, one is created to retrieve the information. - @return The password expiration date. If the profile has no password expiration data (*NOMAX), null is returned. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. + * Returns the password expiration date for the signed-on user. If the profile's password expiration interval is set + * to *NOMAX, null is returned. + *

+ * A connection is required to retrieve this information. If a connection has not been established, one is created + * to retrieve the information. + * + * @return The password expiration date. If the profile has no password expiration data (*NOMAX), null is returned. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. **/ public GregorianCalendar getPasswordExpirationDate() throws AS400SecurityException, IOException { @@ -2279,13 +2457,13 @@ public GregorianCalendar getPasswordExpirationDate() throws AS400SecurityExcepti return (expire == null) ? null : (GregorianCalendar)expire.clone(); } - /** - * Set a flag to indicate whether or not to use the password expiration warning days - * from the QPWDEXPWRN system value. This capability is supported with V6R1M0 - * and later systems with V6R1M0 5761SS1 PTF SI48808 or V7R1M0 5770SS1 PTF SI48809. - * @param useSystem indicates whether or not to use password expiration warning days - * from the QPWDEXPWRN system value + * Set a flag to indicate whether or not to use the password expiration warning days from the QPWDEXPWRN system + * value. This capability is supported with V6R1M0 and later systems with V6R1M0 5761SS1 PTF SI48808 or V7R1M0 + * 5770SS1 PTF SI48809. + * + * @param useSystem indicates whether or not to use password expiration warning days from the QPWDEXPWRN system + * value */ public void setUseSystemPasswordExpirationWarningDays(boolean useSystem) { @@ -2299,15 +2477,15 @@ public void setUseSystemPasswordExpirationWarningDays(boolean useSystem) } /** - * Returns the number of days before password expiration to start warning the user - * based on the value of the QPWDEXPWRN system value. This capability is supported - * with V6R1M0 and later systems with V6R1M0 5761SS1 PTF SI48808 or V7R1M0 5770SS1 PTF SI48809. - * @return The number of days before password expiration to start warning the user. - * If {@link #setUseSystemPasswordExpirationWarningDays} is enabled and supported, - * return the value of the QPWDEXPWRN system value. Otherwise, return - * {@link #getPasswordExpirationWarningDays}. - * @throws AS400SecurityException If a security or authority error occurs. - * @throws IOException If an error occurs while communicating with the system. + * Returns the number of days before password expiration to start warning the user based on the value of the + * QPWDEXPWRN system value. This capability is supported with V6R1M0 and later systems with V6R1M0 5761SS1 PTF + * SI48808 or V7R1M0 5770SS1 PTF SI48809. + * + * @return The number of days before password expiration to start warning the user. If + * {@link #setUseSystemPasswordExpirationWarningDays} is enabled and supported, return the value of the + * QPWDEXPWRN system value. Otherwise, return {@link #getPasswordExpirationWarningDays}. + * @throws AS400SecurityException If a security or authority error occurs. + * @throws IOException If an error occurs while communicating with the system. */ public int getSystemPasswordExpirationWarningDays()throws AS400SecurityException, IOException { @@ -2327,14 +2505,14 @@ public int getSystemPasswordExpirationWarningDays()throws AS400SecurityException return getPasswordExpirationWarningDays(); } - /** - * Determines if the password expiration date for the user profile is within the - * password expiration warning days for the system returned by - * {@link #getPasswordExpirationDays()}. - * @return true if the password expiration date for the user profile is within the - * password expiration days; otherwise, return false - * @throws AS400SecurityException If a security or authority error occurs. - * @throws IOException If an error occurs while communicating with the system. + /** + * Determines if the password expiration date for the user profile is within the password expiration warning days + * for the system returned by {@link #getPasswordExpirationDays()}. + * + * @return true if the password expiration date for the user profile is within the password expiration days; + * otherwise, return false + * @throws AS400SecurityException If a security or authority error occurs. + * @throws IOException If an error occurs while communicating with the system. */ public boolean isInPasswordExpirationWarningDays() throws AS400SecurityException, IOException { @@ -2351,11 +2529,13 @@ public boolean isInPasswordExpirationWarningDays() throws AS400SecurityException /** * Returns the number of days until the user profile's password expires. - *

A connection is required to retrieve this information. If a connection - * has not been established, one is created to retrieve the information. - * @return The number of days until the user profiles' password expires. - * @throws AS400SecurityException If a security or authority error occurs. - * @throws IOException If an error occurs while communicating with the system. + *

+ * A connection is required to retrieve this information. If a connection has not been established, one is created + * to retrieve the information. + * + * @return The number of days until the user profiles' password expires. + * @throws AS400SecurityException If a security or authority error occurs. + * @throws IOException If an error occurs while communicating with the system. */ public int getPasswordExpirationDays() throws AS400SecurityException, IOException { @@ -2371,8 +2551,9 @@ public int getPasswordExpirationDays() throws AS400SecurityException, IOExceptio } /** - Returns the number of days before password expiration to start warning the user. - @return The number of days before expiration to warn the user. + * Returns the number of days before password expiration to start warning the user. + * + * @return The number of days before expiration to warn the user. **/ public static int getPasswordExpirationWarningDays() { @@ -2381,11 +2562,14 @@ public static int getPasswordExpirationWarningDays() } /** - Returns the date of the last successful sign-on. -

A connection is required to retrieve this information. If a connection has not been established, one is created to retrieve the information. - @return The date of the last successful sign-on. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. + * Returns the date of the last successful sign-on. + *

+ * A connection is required to retrieve this information. If a connection has not been established, one is created + * to retrieve the information. + * + * @return The date of the last successful sign-on. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. **/ public GregorianCalendar getPreviousSignonDate() throws AS400SecurityException, IOException { @@ -2401,16 +2585,25 @@ public GregorianCalendar getPreviousSignonDate() throws AS400SecurityException, } /** - Returns a profile token representing the signed-on user profile. -

The returned token will be created single-use with a one hour time to expiration. Subsequent method calls will return the same token, regardless of the token status. -

This function is not supported if the assigned password is *CURRENT. -

This function is only supported if the system is at i5/OS V4R5M0 or greater. - @return A ProfileTokenCredential representing the currently signed on user. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. - @exception InterruptedException If this thread is interrupted. - @deprecated Use {@link #getProfileToken(int,int) getProfileToken(int,int)} instead. + * Returns a profile token representing the signed-on user profile. + *

+ * The returned token will be created single-use with a one hour time to expiration. Subsequent method calls will + * return the same token, regardless of the token status. + *

+ * This function is not supported if the assigned password is *CURRENT. + *

+ * This function is only supported if the system is at i5/OS V4R5M0 or greater. + *

+ * Note: If an additional authentication factor has been set for the AS400 object, it will be used when + * generating the profile token. + * + * @return A ProfileTokenCredential representing the currently signed on user. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. + * @exception InterruptedException If this thread is interrupted. + * @deprecated Use {@link #getProfileToken(int,int) getProfileToken(int,int)} instead. **/ + @Deprecated public ProfileTokenCredential getProfileToken() throws AS400SecurityException, IOException, InterruptedException { connectService(AS400.SIGNON); @@ -2422,18 +2615,28 @@ public ProfileTokenCredential getProfileToken() throws AS400SecurityException, I } /** - Authenticates the assigned user profile and password and returns a corresponding ProfileTokenCredential if successful. -

This function is not supported if the assigned password is *CURRENT and cannot be used to generate a renewable token. This function is only supported if the system is at i5/OS V4R5M0 or greater. - @param tokenType The type of profile token to create. Possible types are defined as fields on the ProfileTokenCredential class: -

- @param timeoutInterval The number of seconds to expiration when the token is created (1-3600). - @return A ProfileTokenCredential representing the signed-on user. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. - @exception InterruptedException If this thread is interrupted. + * Authenticates the assigned user profile and password and returns a corresponding ProfileTokenCredential if + * successful. + *

+ * This function is not supported if the assigned password is *CURRENT and cannot be used to generate a renewable + * token. This function is only supported if the system is at i5/OS V4R5M0 or greater. + *

+ * Note: If an additional authentication factor has been set for the AS400 object, it will be used when + * generating the profile token. + * + * @param tokenType The type of profile token to create. Possible types are defined as fields on the + * ProfileTokenCredential class: + *

+ * @param timeoutInterval The number of seconds to expiration when the token is created (1-3600). + * @return A ProfileTokenCredential representing the signed-on user. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. + * @exception InterruptedException If this thread is interrupted. **/ public ProfileTokenCredential getProfileToken(int tokenType, int timeoutInterval) throws AS400SecurityException, IOException, InterruptedException { @@ -2474,71 +2677,99 @@ public ProfileTokenCredential getProfileToken(int tokenType, int timeoutInterval CredentialVault tempVault = (CredentialVault)credVault_.clone(); tempVault.storeEncodedUsingExternalSeeds(proxySeed, impl_.exchangeSeed(proxySeed)); - impl_.generateProfileToken(profileToken, userId_, tempVault, gssName_); // @mds + impl_.generateProfileToken(profileToken, userId_, tempVault, gssName_); } return profileToken; } /** - Authenticates the given user profile and password and returns a corresponding ProfileTokenCredential if successful. -

Invoking this method does not change the user ID and password assigned to the system or otherwise modify the user or authorities under which the application is running. -

This method generates a single use token with a timeout of one hour. -

This function is only supported if the system is at i5/OS V4R5M0 or greater. -

Note: Providing an incorrect password increments the number of failed sign-on attempts for the user profile, and can result in the profile being disabled. Refer to documentation on the ProfileTokenCredential class for additional restrictions. - @param userId The user profile name. - @param password The user profile password. - @return A ProfileTokenCredential representing the authenticated profile and password. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. - @exception InterruptedException If this thread is interrupted. - @deprecated Use {@link #getProfileToken(String, char[]) getProfileToken(String, char[])} instead. - **/ - public ProfileTokenCredential getProfileToken(String userId, String password) throws AS400SecurityException, IOException, InterruptedException - { + * Authenticates the given user profile and password and returns a corresponding ProfileTokenCredential if + * successful. + *

+ * Invoking this method does not change the user ID and password assigned to the system or otherwise modify the user + * or authorities under which the application is running. + *

+ * This method generates a single use token with a timeout of one hour. + *

+ * This function is only supported if the system is at i5/OS V4R5M0 or greater. + *

+ * Note: Providing an incorrect password increments the number of failed sign-on attempts for the user + * profile, and can result in the profile being disabled. Refer to documentation on the + * ProfileTokenCredential class for additional restrictions. + * + * @param userId The user profile name. + * @param password The user profile password. + * @return A ProfileTokenCredential representing the authenticated profile and password. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. + * @exception InterruptedException If this thread is interrupted. + * @deprecated Use {@link #getProfileToken(String, char[]) getProfileToken(String, char[])} instead. + **/ + @Deprecated + public ProfileTokenCredential getProfileToken(String userId, String password) throws AS400SecurityException, IOException, InterruptedException { return getProfileToken(userId, password, ProfileTokenCredential.TYPE_SINGLE_USE, 3600); } /** - Authenticates the given user profile and password and returns a corresponding ProfileTokenCredential if successful. -

Invoking this method does not change the user ID and password assigned to the system or otherwise modify the user or authorities under which the application is running. -

This method generates a single use token with a timeout of one hour. -

This function is only supported if the system is at i5/OS V4R5M0 or greater. -

Note: Providing an incorrect password increments the number of failed sign-on attempts for the user profile, - and can result in the profile being disabled. Refer to documentation on the ProfileTokenCredential class for additional restrictions. - @param userId The user profile name. - @param password The user profile password. - @return A ProfileTokenCredential representing the authenticated profile and password. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. - @exception InterruptedException If this thread is interrupted. - **/ - public ProfileTokenCredential getProfileToken(String userId, char[] password) throws AS400SecurityException, IOException, InterruptedException - { + * Authenticates the given user profile and password and returns a corresponding ProfileTokenCredential if + * successful. + *

+ * Invoking this method does not change the user ID and password assigned to the system or otherwise modify the user + * or authorities under which the application is running. + *

+ * This method generates a single use token with a timeout of one hour. + *

+ * This function is only supported if the system is at i5/OS V4R5M0 or greater. + *

+ * Note: Providing an incorrect password increments the number of failed sign-on attempts for the user + * profile, and can result in the profile being disabled. Refer to documentation on the + * ProfileTokenCredential class for additional restrictions. + * + * @param userId The user profile name. + * @param password The user profile password. + * @return A ProfileTokenCredential representing the authenticated profile and password. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. + * @exception InterruptedException If this thread is interrupted. + **/ + public ProfileTokenCredential getProfileToken(String userId, char[] password) throws AS400SecurityException, IOException, InterruptedException { return getProfileToken(userId, password, ProfileTokenCredential.TYPE_SINGLE_USE, 3600); } /** - Authenticates the given user profile and password and returns a corresponding ProfileTokenCredential if successful. -

Invoking this method does not change the user ID and password assigned to the system or otherwise modify the user or authorities under which the application is running. -

This function is only supported if the system is at i5/OS V4R5M0 or greater. -

Note: Providing an incorrect password increments the number of failed sign-on attempts for the user profile, and can - result in the profile being disabled. Refer to documentation on the ProfileTokenCredential class for additional restrictions. - @param userId The user profile name. - @param password The user profile password. - @param tokenType The type of profile token to create. Possible types are defined as fields on the ProfileTokenCredential class: -

- @param timeoutInterval The number of seconds to expiration when the token is created (1-3600). - @return A ProfileTokenCredential representing the authenticated profile and password. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. - @exception InterruptedException If this thread is interrupted. - @deprecated Use {@link #getProfileToken(String, char[],int,int) getProfileToken(String, char[],int,int)} instead. - **/ + * Authenticates the given user profile and password and returns a corresponding ProfileTokenCredential if + * successful. + *

+ * Invoking this method does not change the user ID and password assigned to the system or otherwise modify the user + * or authorities under which the application is running. + *

+ * This function is only supported if the system is at i5/OS V4R5M0 or greater. + *

+ * Note: Providing an incorrect password increments the number of failed sign-on attempts for the user + * profile, and can result in the profile being disabled. Refer to documentation on the + * ProfileTokenCredential class for additional restrictions. + * + * @param userId The user profile name. + * @param password The user profile password. + * @param tokenType The type of profile token to create. Possible types are defined as fields on the + * ProfileTokenCredential class: + *

+ * @param timeoutInterval The number of seconds to expiration when the token is created (1-3600). + * @return A ProfileTokenCredential representing the authenticated profile and password. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. + * @exception InterruptedException If this thread is interrupted. + * @deprecated Use {@link #getProfileToken(String, char[],int,int) getProfileToken(String, char[],int,int)} instead. + **/ + @Deprecated public ProfileTokenCredential getProfileToken(String userId, String password, int tokenType, int timeoutInterval) throws AS400SecurityException, IOException, InterruptedException { char[] passwordChars = (password == null) ? null : password.toCharArray(); @@ -2554,24 +2785,35 @@ public ProfileTokenCredential getProfileToken(String userId, String password, in } /** - Authenticates the given user profile and password and returns a corresponding ProfileTokenCredential if successful. -

Invoking this method does not change the user ID and password assigned to the system or otherwise modify the user or authorities under which the application is running. -

This function is only supported if the system is at i5/OS V4R5M0 or greater. -

Note: Providing an incorrect password increments the number of failed sign-on attempts for the user profile, and can - result in the profile being disabled. Refer to documentation on the ProfileTokenCredential class for additional restrictions. - @param userId The user profile name. - @param password The user profile password. - @param tokenType The type of profile token to create. Possible types are defined as fields on the ProfileTokenCredential class: -

- @param timeoutInterval The number of seconds to expiration when the token is created (1-3600). - @return A ProfileTokenCredential representing the authenticated profile and password. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. - @exception InterruptedException If this thread is interrupted. + * Authenticates the given user profile and password and returns a corresponding ProfileTokenCredential if + * successful. + *

+ * Invoking this method does not change the user ID and password assigned to the system or otherwise modify the user + * or authorities under which the application is running. + *

+ * This function is only supported if the system is at i5/OS V4R5M0 or greater. + *

+ * Note: Providing an incorrect password increments the number of failed sign-on attempts for the user + * profile, and can result in the profile being disabled. Refer to documentation on the + * ProfileTokenCredential class for additional restrictions. + * + * @param userId The user profile name. + * @param password The user profile password. + * @param tokenType The type of profile token to create. Possible types are defined as fields on the + * ProfileTokenCredential class: + *

+ * @param timeoutInterval The number of seconds to expiration when the token is created (1-3600). + * @return A ProfileTokenCredential representing the authenticated profile and password. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. + * @exception InterruptedException If this thread is interrupted. **/ public ProfileTokenCredential getProfileToken(String userId, char[] password, int tokenType, int timeoutInterval) throws AS400SecurityException, IOException, InterruptedException { @@ -2618,8 +2860,10 @@ public ProfileTokenCredential getProfileToken(String userId, char[] password, in } /** - Returns the name of the middle-tier machine where the proxy server is running. - @return The name of the middle-tier machine where the proxy server is running, or an empty string ("") if not set. + * Returns the name of the middle-tier machine where the proxy server is running. + * + * @return The name of the middle-tier machine where the proxy server is running, or an empty string ("") if not + * set. **/ public String getProxyServer() { @@ -2628,18 +2872,21 @@ public String getProxyServer() } /** - Returns the release of the IBM i system. -

A connection is required to the system in order to retrieve this information. If a connection has not been established, one is created to retrieve the system information. - @return The release of the IBM i system. For example, version 5, release 1, modification level 0, returns 1. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. + * Returns the release of the IBM i system. + *

+ * A connection is required to the system in order to retrieve this information. If a connection has not been + * established, one is created to retrieve the system information. + * + * @return The release of the IBM i system. For example, version 5, release 1, modification level 0, returns 1. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. **/ public int getRelease() throws AS400SecurityException, IOException { if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Getting release level."); if (signonInfo_ == null) { - chooseImpl(); - signon(false); + chooseImpl(); + signon(false); } int release = signonInfo_.version.getRelease(); if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Release level:", release); @@ -2647,8 +2894,14 @@ public int getRelease() throws AS400SecurityException, IOException return release; } - // Converts a service constant to a service name. - public static String getServerName(int service)//@Q10 + /** + * Converts a service constant to the string representation of the service. For example, the integer AS400.File + * corresponds to the string "as-file". + * + * @param service The service represented by it's integer value. + * @return The string representation of the service. + */ + public static String getServerName(int service) { switch (service) { @@ -2676,20 +2929,22 @@ public static String getServerName(int service)//@Q10 } /** - Returns the service port stored in the service port table for the specified service. - @param service The name of the service. Valid services are: -

- @return The port specified in the service port table. The value {@link #USE_PORT_MAPPER USE_PORT_MAPPER} will be returned if the service has not been set, and the service has not been connected. + * Returns the service port stored in the service port table for the specified service. + * + * @param service The name of the service. Valid services are: + * + * @return The port specified in the service port table. The value {@link #USE_PORT_MAPPER USE_PORT_MAPPER} will be + * returned if the service has not been set, and the service has not been connected. **/ public int getServicePort(int service) { @@ -2714,11 +2969,14 @@ public int getServicePort(int service) } /** - Returns the date for the current sign-on. -

A connection is required to the system to retrieve this information. If a connection has not been established, one is created to retrieve the system information. - @return The date for the current sign-on. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. + * Returns the date for the current sign-on. + *

+ * A connection is required to the system to retrieve this information. If a connection has not been established, + * one is created to retrieve the system information. + * + * @return The date for the current sign-on. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. **/ public GregorianCalendar getSignonDate() throws AS400SecurityException, IOException { @@ -2734,10 +2992,11 @@ public GregorianCalendar getSignonDate() throws AS400SecurityException, IOExcept } /** - Returns the sign-on handler that is used by this object. Never returns null. - @return The sign-on handler. - @see #setSignonHandler - @see #setDefaultSignonHandler + * Returns the sign-on handler that is used by this object. Never returns null. + * + * @return The sign-on handler. + * @see #setSignonHandler + * @see #setDefaultSignonHandler **/ public SignonHandler getSignonHandler() { @@ -2745,8 +3004,9 @@ public SignonHandler getSignonHandler() } /** - Returns a copy of the socket options object. - @return The socket options object. + * Returns a copy of the socket options object. + * + * @return The socket options object. **/ public SocketProperties getSocketProperties() { @@ -2757,8 +3017,10 @@ public SocketProperties getSocketProperties() } /** - Returns the name of the IBM i system. The system name is provided on the constructor or may have been provided by the user at the sign-on prompt. - @return The name of the IBM i system, or an empty string ("") if not set. + * Returns the name of the IBM i system. The system name is provided on the constructor or may have been provided by + * the user at the sign-on prompt. + * + * @return The name of the IBM i system, or an empty string ("") if not set. **/ public String getSystemName() { @@ -2767,20 +3029,19 @@ public String getSystemName() } /** - Returns the time zone of the IBM i system. - The TimeZone object will have the correct UTC offset for the system. - @return A TimeZone object representing the time zone for the system. - @exception AS400SecurityException If a security or authority error - occurs. - @exception ErrorCompletingRequestException If an error occurs before - the request is completed. - @exception InterruptedException If this thread is interrupted. - @exception IOException If an error occurs while communicating with - the system. - @exception ObjectDoesNotExistException If the API used to retrieve the information does not exist on the system. - @see DateTimeConverter#timeZoneForSystem - @deprecated Use {@link #getTimeZone() getTimeZone()} instead. - **/ + * Returns the time zone of the IBM i system. The TimeZone object will have the correct UTC offset for the system. + * + * @return A TimeZone object representing the time zone for the system. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception ErrorCompletingRequestException If an error occurs before the request is completed. + * @exception InterruptedException If this thread is interrupted. + * @exception IOException If an error occurs while communicating with the system. + * @exception ObjectDoesNotExistException If the API used to retrieve the information does not exist on the + * system. + * @see DateTimeConverter#timeZoneForSystem + * @deprecated Use {@link #getTimeZone() getTimeZone()} instead. + **/ + @Deprecated public TimeZone getSystemTimeZone() throws AS400SecurityException, ErrorCompletingRequestException, @@ -2792,18 +3053,16 @@ public TimeZone getSystemTimeZone() } /** - Returns the time zone of the IBM i system. - The TimeZone object will have the correct UTC offset for the system. - @return A TimeZone object representing the time zone for the system. - @exception AS400SecurityException If a security or authority error - occurs. - @exception ErrorCompletingRequestException If an error occurs before - the request is completed. - @exception InterruptedException If this thread is interrupted. - @exception IOException If an error occurs while communicating with - the system. - @exception ObjectDoesNotExistException If the API used to retrieve the information does not exist on the system. - @see DateTimeConverter#timeZoneForSystem + * Returns the time zone of the IBM i system. The TimeZone object will have the correct UTC offset for the system. + * + * @return A TimeZone object representing the time zone for the system. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception ErrorCompletingRequestException If an error occurs before the request is completed. + * @exception InterruptedException If this thread is interrupted. + * @exception IOException If an error occurs while communicating with the system. + * @exception ObjectDoesNotExistException If the API used to retrieve the information does not exist on the + * system. + * @see DateTimeConverter#timeZoneForSystem **/ public TimeZone getTimeZone() throws AS400SecurityException, @@ -2821,10 +3080,11 @@ public TimeZone getTimeZone() } /** - * Returns the timezone of the IBM i, if available. If the timezone is not available, - * then the default timezone for the client will be return. - * @param system System to get the timezone from - * @return The timezone of the IBM i if available. + * Returns the timezone of the IBM i, if available. If the timezone is not available, then the default timezone for + * the client will be return. + * + * @param system System to get the timezone from + * @return The timezone of the IBM i if available. */ public static TimeZone getDefaultTimeZone(AS400 system) { @@ -2849,8 +3109,10 @@ public static TimeZone getDefaultTimeZone(AS400 system) /** - Returns the user ID. The user ID returned may be set as a result of the constructor, or it may be what the user typed in at the sign-on prompt. - @return The user ID, or an empty string ("") if not set. + * Returns the user ID. The user ID returned may be set as a result of the constructor, or it may be what the user + * typed in at the sign-on prompt. + * + * @return The user ID, or an empty string ("") if not set. **/ public String getUserId() { @@ -2860,9 +3122,15 @@ public String getUserId() } /** - Returns the user ID. The user ID returned may be set as a result of the constructor, or it may be what the user typed in at the sign-on prompt. - @param forceRefresh If true, force the current userID information to be reloaded. When running natively with system name specified as localhost, this will obtain the user profile under which the thread is currently running. This may have changed since object construction, if a profile swap has been performed on the thread. If false, or if running remotely, then this method behaves identically to {@link #getUserId getUserId()}. - @return The user ID, or an empty string ("") if not set. + * Returns the user ID. The user ID returned may be set as a result of the constructor, or it may be what the user + * typed in at the sign-on prompt. + * + * @param forceRefresh If true, force the current userID information to be reloaded. When running natively with + * system name specified as localhost, this will obtain the user profile under + * which the thread is currently running. This may have changed since object construction, if a + * profile swap has been performed on the thread. If false, or if running remotely, then this + * method behaves identically to {@link #getUserId getUserId()}. + * @return The user ID, or an empty string ("") if not set. **/ public String getUserId(boolean forceRefresh) { @@ -2891,11 +3159,14 @@ public String getUserId(boolean forceRefresh) } /** - Returns the version of the IBM i system. -

A connection is required to the system to retrieve this information. If a connection has not been established, one is created to retrieve the system information. - @return The version of the IBM i system. For example, version 5, release 1, modification level 0, returns 5. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. + * Returns the version of the IBM i system. + *

+ * A connection is required to the system to retrieve this information. If a connection has not been established, + * one is created to retrieve the system information. + * + * @return The version of the IBM i system. For example, version 5, release 1, modification level 0, returns 5. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. **/ public int getVersion() throws AS400SecurityException, IOException { @@ -2911,11 +3182,15 @@ public int getVersion() throws AS400SecurityException, IOException } /** - Returns the version, release, and modification level for the system. -

A connection is required to the system to retrieve this information. If a connection has not been established, one is created to retrieve the system information. - @return The high 16-bit is the version, the next 8 bits is the release, and the low 8 bits is the modification level. Thus version 5, release 1, modification level 0, returns 0x00050100. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. + * Returns the version, release, and modification level for the system. + *

+ * A connection is required to the system to retrieve this information. If a connection has not been established, + * one is created to retrieve the system information. + * + * @return The high 16-bit is the version, the next 8 bits is the release, and the low 8 bits is the modification + * level. Thus version 5, release 1, modification level 0, returns 0x00050100. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. **/ public int getVRM() throws AS400SecurityException, IOException { @@ -2953,9 +3228,11 @@ protected void setVRM(int v, int r, int m) } /** - Initialize conversion table for the given CCSID. The default EBCDIC to unicode converters are not shipped with some browsers. This method can be used to check and download converters if they are not available locally. - @param ccsid the CCSID for the conversion table to initialize. - * @throws UnsupportedEncodingException If the Character Encoding is not supported. + * Initialize conversion table for the given CCSID. The default EBCDIC to unicode converters are not shipped with + * some browsers. This method can be used to check and download converters if they are not available locally. + * + * @param ccsid the CCSID for the conversion table to initialize. + * @throws UnsupportedEncodingException If the Character Encoding is not supported. **/ public void initializeConverter(int ccsid) throws UnsupportedEncodingException { @@ -2974,10 +3251,14 @@ public void initializeConverter(int ccsid) throws UnsupportedEncodingException } /** - Indicates if any service is currently connected through this object. -

A service is considered "connected" if connectService() has been called, or an implicit connect has been done by the service, and disconnectService() or disconnectAllServices() has not been called. If the most recent attempt to contact the service failed with an exception, the service is considered disconnected. - @return true if any service is connected; false otherwise. - @see #isConnectionAlive + * Indicates if any service is currently connected through this object. + *

+ * A service is considered "connected" if connectService() has been called, or an implicit connect has been done by + * the service, and disconnectService() or disconnectAllServices() has not been called. If the most recent attempt + * to contact the service failed with an exception, the service is considered disconnected. + * + * @return true if any service is connected; false otherwise. + * @see #isConnectionAlive **/ public boolean isConnected() { @@ -2993,22 +3274,26 @@ public boolean isConnected() } /** - Indicates if a service is currently connected through this object. -

A service is considered "connected" if connectService() has been called, or an implicit connect has been done by the service, and disconnectService() or disconnectAllServices() has not been called. If the most recent attempt to contact the service failed with an exception, the service is considered disconnected. - @param service The name of the service. Valid services are: -

- @return true if service is connected; false otherwise. - @see #isConnectionAlive + * Indicates if a service is currently connected through this object. + *

+ * A service is considered "connected" if connectService() has been called, or an implicit connect has been done by + * the service, and disconnectService() or disconnectAllServices() has not been called. If the most recent attempt + * to contact the service failed with an exception, the service is considered disconnected. + * + * @param service The name of the service. Valid services are: + *

+ * @return true if service is connected; false otherwise. + * @see #isConnectionAlive **/ public boolean isConnected(int service) { @@ -3023,14 +3308,20 @@ public boolean isConnected(int service) } /** - Tests the connection to the system, to verify that it is still working. - This is similar in concept to "pinging" the system over the connection. - If no services have been connected, this method returns false; it doesn't implicitly connect services. -

Note: This method is not fully supported until IBM i 7.1. If running to IBM i 6.1 or lower, then the behavior of this method matches that of {@link #isConnected() isConnected()}, and therefore may incorrectly return true if the connection has failed recently. -

Note: If the only service connected is {@link #RECORDACCESS RECORDACCESS}, then this method defaults to the behavior of {@link #isConnected() isConnected()}. - @return true if the connection is still working; false otherwise. - @see #isConnected - @see AS400JPing + * Tests the connection to the system, to verify that it is still working. This is similar in concept to "pinging" + * the system over the connection. If no services have been connected, this method returns false; it doesn't + * implicitly connect services. + *

+ * Note: This method is not fully supported until IBM i 7.1. If running to IBM i 6.1 or lower, then the + * behavior of this method matches that of {@link #isConnected() isConnected()}, and therefore may incorrectly + * return true if the connection has failed recently. + *

+ * Note: If the only service connected is {@link #RECORDACCESS RECORDACCESS}, then this method defaults to the + * behavior of {@link #isConnected() isConnected()}. + * + * @return true if the connection is still working; false otherwise. + * @see #isConnected + * @see AS400JPing **/ public boolean isConnectionAlive() { @@ -3041,28 +3332,33 @@ public boolean isConnectionAlive() return alive; } - /** - Tests the connection to a service on the system, to verify that it is still working. - This is similar in concept to "pinging" the system over the connection. - If no services have been connected, this method returns false; it doesn't implicitly connect services. -

Note: This method is not fully supported until IBM i 7.1. If running to IBM i 6.1 or lower, then the behavior of this method matches that of {@link #isConnected() isConnected()}, and therefore may incorrectly return true if the connection has failed recently. -

Note: If the specified service is {@link #RECORDACCESS RECORDACCESS}, then this method defaults to the behavior of {@link #isConnected() isConnected()}. - @param service The name of the service. Valid services are: -

- @return true if the connection to the service is still working; false otherwise. - @see #isConnected - @see AS400JPing + * Tests the connection to a service on the system, to verify that it is still working. This is similar in concept + * to "pinging" the system over the connection. If no services have been connected, this method returns false; it + * doesn't implicitly connect services. + *

+ * Note: This method is not fully supported until IBM i 7.1. If running to IBM i 6.1 or lower, then the + * behavior of this method matches that of {@link #isConnected() isConnected()}, and therefore may incorrectly + * return true if the connection has failed recently. + *

+ * Note: If the specified service is {@link #RECORDACCESS RECORDACCESS}, then this method defaults to the behavior + * of {@link #isConnected() isConnected()}. + * + * @param service The name of the service. Valid services are: + *

+ * @return true if the connection to the service is still working; false otherwise. + * @see #isConnected + * @see AS400JPing **/ public boolean isConnectionAlive(int service) { @@ -3075,8 +3371,11 @@ public boolean isConnectionAlive(int service) } /** - Returns the sign-on prompting mode for this object. If true, then messages are displayed. If warnings or errors occur, the sign-on and change password dialogs are displayed if needed. If false, warnings and errors result in exceptions, and password dialogs are not displayed. The caller has to provide the user ID and password. - @return true if using GUI; false otherwise. + * Returns the sign-on prompting mode for this object. If true, then messages are displayed. If warnings or errors + * occur, the sign-on and change password dialogs are displayed if needed. If false, warnings and errors result in + * exceptions, and password dialogs are not displayed. The caller has to provide the user ID and password. + * + * @return true if using GUI; false otherwise. **/ public boolean isGuiAvailable() { @@ -3085,8 +3384,9 @@ public boolean isGuiAvailable() } /** - Indicates if this object is representing the system you are currently running on. - @return true if you are running on the local system; false otherwise. + * Indicates if this object is representing the system you are currently running on. + * + * @return true if you are running on the local system; false otherwise. **/ public boolean isLocal() { @@ -3095,8 +3395,12 @@ public boolean isLocal() } /** - When your Java program runs on the system, some Toolbox classes access data via a call to an API instead of making a socket call to the system. There are minor differences in the behavior of the classes when they use API calls instead of socket calls. If your program is affected by these differences you can check whether the Toolbox classes will use socket calls instead of API calls by using this method. - @return true if you have indicated that the services must use sockets; false otherwise. + * When your Java program runs on the system, some Toolbox classes access data via a call to an API instead of + * making a socket call to the system. There are minor differences in the behavior of the classes when they use API + * calls instead of socket calls. If your program is affected by these differences you can check whether the Toolbox + * classes will use socket calls instead of API calls by using this method. + * + * @return true if you have indicated that the services must use sockets; false otherwise. **/ public boolean isMustUseSockets() { @@ -3105,8 +3409,9 @@ public boolean isMustUseSockets() } /** - Indicates if checkboxes should be shown on the sign-on dialog. - @return true if checkboxes should be shown; false otherwise. + * Indicates if checkboxes should be shown on the sign-on dialog. + * + * @return true if checkboxes should be shown; false otherwise. **/ public boolean isShowCheckboxes() { @@ -3144,8 +3449,9 @@ private static boolean isSystemNameLocal(String systemName) } /** - Indicates whether threads are used in communication with the host servers. - @return true if threads are used; false otherwise. + * Indicates whether threads are used in communication with the host servers. + * + * @return true if threads are used; false otherwise. **/ public boolean isThreadUsed() { @@ -3154,8 +3460,10 @@ public boolean isThreadUsed() } /** - Indicates if the default user should be used by this object. If the default user is not used and a user ID was not specified on the constructor, then the user will be prompted for a user ID. - @return true if default user should be used; false otherwise. + * Indicates if the default user should be used by this object. If the default user is not used and a user ID was + * not specified on the constructor, then the user will be prompted for a user ID. + * + * @return true if default user should be used; false otherwise. **/ public boolean isUseDefaultUser() { @@ -3164,8 +3472,10 @@ public boolean isUseDefaultUser() } /** - Indicates if the password cache is being used by this object. If the password cache is not used, the user will always be prompted for password if one was not provided. - @return true if password cache is being used; false otherwise. + * Indicates if the password cache is being used by this object. If the password cache is not used, the user will + * always be prompted for password if one was not provided. + * + * @return true if password cache is being used; false otherwise. **/ public boolean isUsePasswordCache() { @@ -3175,9 +3485,10 @@ public boolean isUsePasswordCache() /** * Is the AS400 object configured to use a pass phrase + * * @return true if pass phrase can be used - * @throws AS400SecurityException If a security or authority error occurs. - * @throws IOException If an error occurs while communicating with the system. + * @throws AS400SecurityException If a security or authority error occurs. + * @throws IOException If an error occurs while communicating with the system. */ public boolean isUsePassphrase() throws AS400SecurityException, IOException { @@ -3518,8 +3829,9 @@ private void readObject(ObjectInputStream in) throws ClassNotFoundException, IOE } /** - Removes a listener from the connection event list. - @param listener The listener object. + * Removes a listener from the connection event list. + * + * @param listener The listener object. **/ public void removeConnectionListener(ConnectionListener listener) { @@ -3544,8 +3856,9 @@ public void removeConnectionListener(ConnectionListener listener) } /** - Removes the default user for the given system name. - @param systemName The name of the IBM i system. + * Removes the default user for the given system name. + * + * @param systemName The name of the IBM i system. **/ public static void removeDefaultUser(String systemName) { @@ -3557,9 +3870,11 @@ public static void removeDefaultUser(String systemName) } /** - Removes the password cache entry associated with this system name and user ID. Only applies within this Java virtual machine. - @param systemName The name of the IBM i system. - @param userId The user profile name. + * Removes the password cache entry associated with this system name and user ID. Only applies within this Java + * virtual machine. + * + * @param systemName The name of the IBM i system. + * @param userId The user profile name. **/ public static void removePasswordCacheEntry(String systemName, String userId) { @@ -3618,8 +3933,9 @@ else if (longName != null && longName.equalsIgnoreCase((String)secobj[0]) && us } /** - Removes a property changed listener from the listener list. - @param listener The listener object. + * Removes a property changed listener from the listener list. + * + * @param listener The listener object. **/ public void removePropertyChangeListener(PropertyChangeListener listener) { @@ -3633,8 +3949,9 @@ public void removePropertyChangeListener(PropertyChangeListener listener) } /** - Removes a listener from the veto list. - @param listener The listener object. + * Removes a listener from the veto list. + * + * @param listener The listener object. **/ public void removeVetoableChangeListener(VetoableChangeListener listener) { @@ -3648,10 +3965,10 @@ public void removeVetoableChangeListener(VetoableChangeListener listener) } /** - Disconnects all services, and clears the sign-on information. - This intent of this method is to "wipe the slate clean" for this AS400 object, enabling connection - properties to be subsequently changed. - @see #disconnectAllServices + * Disconnects all services, and clears the sign-on information. This intent of this method is to "wipe the slate + * clean" for this AS400 object, enabling connection properties to be subsequently changed. + * + * @see #disconnectAllServices **/ public synchronized void resetAllServices() { @@ -3810,9 +4127,13 @@ private void sendSignonRequest() throws AS400SecurityException, IOException } /** - Sets or resets the identity token for this object. Using this method will clear any previously set authentication information. -

Note: Authentication via IdentityToken is supported in operating system release V5R3M0 and by PTF in operating system releases V5R2M0 and V5R1M0. - @param identityToken The identity token. + * Sets or resets the identity token for this object. Using this method will clear any previously set authentication + * information. + *

+ * Note: Authentication via IdentityToken is supported in operating system release V5R3M0 and by PTF in operating + * system releases V5R2M0 and V5R1M0. + * + * @param identityToken The identity token. **/ public void setIdentityToken(byte[] identityToken) { @@ -3829,14 +4150,22 @@ public void setIdentityToken(byte[] identityToken) } } - public void setAdditionalAuthenticationFactor(char[] additionalAuthenticationFactor) + /** + * Set the additional authentication factor for the AS400 object. This will be used when establishing host server + * connections if the IBM i server supports multifactor authentication. + * + * @param additionalAuthFactor The additional authentication factor. + */ + public void setAdditionalAuthenticationFactor(char[] additionalAuthFactor) { if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Setting additional authentication factor. Length: " - + ((additionalAuthenticationFactor == null) ? 0 : additionalAuthenticationFactor.length)); + + ((additionalAuthFactor == null) ? 0 : additionalAuthFactor.length)); - additionalAuthenticationFactor_ = null; - if (null != additionalAuthenticationFactor && 0 < additionalAuthenticationFactor.length ) - additionalAuthenticationFactor_ = Arrays.copyOf(additionalAuthenticationFactor, additionalAuthenticationFactor.length); + additionalAuthenticationFactor_ = (null != additionalAuthFactor && 0 < additionalAuthFactor.length ) + ? Arrays.copyOf(additionalAuthFactor, additionalAuthFactor.length) : null; + + if (impl_ != null) + impl_.setAdditionalAuthenticationFactor(additionalAuthenticationFactor_); } // Store information in password cache. @@ -3865,10 +4194,11 @@ private static void setCacheEntry(String systemName, String userId, CredentialVa } /** - Sets the CCSID to be used for this object. The CCSID property cannot be changed once a connection to the - system has been established. - @param ccsid The CCSID to use for this object. - @exception PropertyVetoException If any of the registered listeners vetos the property change. + * Sets the CCSID to be used for this object. The CCSID property cannot be changed once a connection to the system + * has been established. + * + * @param ccsid The CCSID to use for this object. + * @exception PropertyVetoException If any of the registered listeners vetos the property change. **/ public void setCcsid(int ccsid) throws PropertyVetoException { @@ -3897,13 +4227,14 @@ public void setCcsid(int ccsid) throws PropertyVetoException } /** - Sets the relational database name (RDB name) used for record-level access (DDM) connections. The RDB name - corresponds to the independent auxiliary storage pool (IASP) that it is using on the system. The RDB name - cannot be changed while this object is actively connected to the {@link #RECORDACCESS RECORDACCESS} service; - you must call {@link #disconnectService(int) AS400.disconnectService(AS400.RECORDACCESS)} first. - @param ddmRDB The name of the IASP or RDB to use, or null to indicate the default system ASP should be used. - @see #isConnected(int) - @see #getDDMRDB + * Sets the relational database name (RDB name) used for record-level access (DDM) connections. The RDB name + * corresponds to the independent auxiliary storage pool (IASP) that it is using on the system. The RDB name cannot + * be changed while this object is actively connected to the {@link #RECORDACCESS RECORDACCESS} service; you must + * call {@link #disconnectService(int) AS400.disconnectService(AS400.RECORDACCESS)} first. + * + * @param ddmRDB The name of the IASP or RDB to use, or null to indicate the default system ASP should be used. + * @see #isConnected(int) + * @see #getDDMRDB **/ public void setDDMRDB(String ddmRDB) { @@ -3923,14 +4254,22 @@ public void setDDMRDB(String ddmRDB) } /** - Sets the default sign-on handler, globally across the JVM. - The specified handler object will be called at runtime if any AS400 object needs to obtain additional signon information, and a sign-on handler has not been set on the AS400 object via {@link #setSignonHandler setSignonHandler()}. -
Users are advised to implement the default sign-on handler in a thread-safe manner, since it may occasionally be in simultaneous use by multiple threads. -
If a default sign-on handler is not set, then the name of the default sign-on handler class is retrieved from the com.ibm.as400.access.AS400.signonHandler system property. -
If not specified, an internal AWT-based sign-on handler is used. -

Note: This property may also be set by specifying a fully-qualified class name in Java system property com.ibm.as400.access.AS400.signonHandler - @param handler The sign-on handler. Specifying null will reset the default sign-on handler to the internal AWT-based handler. - @see #getDefaultSignonHandler + * Sets the default sign-on handler, globally across the JVM. The specified handler object will be called at runtime + * if any AS400 object needs to obtain additional signon information, and a sign-on handler has not been set on the + * AS400 object via {@link #setSignonHandler setSignonHandler()}.
+ * Users are advised to implement the default sign-on handler in a thread-safe manner, since it may occasionally be + * in simultaneous use by multiple threads.
+ * If a default sign-on handler is not set, then the name of the default sign-on handler class is retrieved from the + * com.ibm.as400.access.AS400.signonHandler system property. + *
+ * If not specified, an internal AWT-based sign-on handler is used. + *

+ * Note: This property may also be set by specifying a fully-qualified class name in Java system property + * com.ibm.as400.access.AS400.signonHandler + * + * @param handler The sign-on handler. Specifying null will reset the default sign-on handler to the + * internal AWT-based handler. + * @see #getDefaultSignonHandler **/ public static void setDefaultSignonHandler(SignonHandler handler) { @@ -3943,10 +4282,14 @@ public static void setDefaultSignonHandler(SignonHandler handler) } /** - Sets the default user for a given system name. The default user is the user ID that is used to connect if a user ID is not provided for that system name. There can be only one default user per system name. Once the default user is set, it cannot be overridden. To change the default user, the caller should remove the default user and then set it. - @param systemName The name of the IBM i system. - @param userId The user profile name. - @return true if default user has been set; false otherwise. + * Sets the default user for a given system name. The default user is the user ID that is used to connect if a user + * ID is not provided for that system name. There can be only one default user per system name. Once the default + * user is set, it cannot be overridden. To change the default user, the caller should remove the default user and + * then set it. + * + * @param systemName The name of the IBM i system. + * @param userId The user profile name. + * @return true if default user has been set; false otherwise. **/ public static boolean setDefaultUser(String systemName, String userId) { @@ -3983,8 +4326,9 @@ public static boolean setDefaultUser(String systemName, String userId) } /** - * Sets the GSS manager to be used for all GSS operations. - * @param gssMgr The GSS manager object. + * Sets the GSS manager to be used for all GSS operations. + * + * @param gssMgr The GSS manager object. **/ public static void setGSSManager(GSSManager gssMgr) { @@ -3997,8 +4341,12 @@ static GSSManager getGSSManager() { } /** - Sets the GSS credential for this object. Using this method will set the authentication scheme to {@link #AUTHENTICATION_SCHEME_GSS_TOKEN AUTHENTICATION_SCHEME_GSS_TOKEN}. Only one authentication means (Kerberos ticket, profile token, identity token, or password) can be used at a single time. Using this method will clear any previously set authentication information. - @param gssCredential The GSS credential object. + * Sets the GSS credential for this object. Using this method will set the authentication scheme to + * {@link #AUTHENTICATION_SCHEME_GSS_TOKEN AUTHENTICATION_SCHEME_GSS_TOKEN}. Only one authentication means (Kerberos + * ticket, profile token, identity token, or password) can be used at a single time. Using this method will clear + * any previously set authentication information. + * + * @param gssCredential The GSS credential object. **/ public void setGSSCredential(GSSCredential gssCredential) { @@ -4021,13 +4369,17 @@ public void setGSSCredential(GSSCredential gssCredential) } /** - Sets the option for how the JGSS framework will be used to retrieve a GSS token for authenticating to the system. By default, if no password or profile token is set on this object, it will attempt to retrieve a GSS token. If that retrieval fails, a sign-on dialog can be presented, or on the system, the current user profile information can be used. This option can also be set to only do the GSS token retrieval or to skip the GSS token retrieval. - @param gssOption A constant indicating how GSS will be used. Valid values are: -

+ * Sets the option for how the JGSS framework will be used to retrieve a GSS token for authenticating to the system. + * By default, if no password or profile token is set on this object, it will attempt to retrieve a GSS token. If + * that retrieval fails, a sign-on dialog can be presented, or on the system, the current user profile information + * can be used. This option can also be set to only do the GSS token retrieval or to skip the GSS token retrieval. + * + * @param gssOption A constant indicating how GSS will be used. Valid values are: + * **/ public void setGSSOption(int gssOption) { @@ -4039,8 +4391,12 @@ public void setGSSOption(int gssOption) } /** - Sets the GSS name for this object. Using this method will set the authentication scheme to {@link #AUTHENTICATION_SCHEME_GSS_TOKEN AUTHENTICATION_SCHEME_GSS_TOKEN}. Only one authentication means (Kerberos ticket, profile token, identity token, or password) can be used at a single time. Using this method will clear any previously set authentication information. - @param gssName The GSS name string. + * Sets the GSS name for this object. Using this method will set the authentication scheme to + * {@link #AUTHENTICATION_SCHEME_GSS_TOKEN AUTHENTICATION_SCHEME_GSS_TOKEN}. Only one authentication means (Kerberos + * ticket, profile token, identity token, or password) can be used at a single time. Using this method will clear + * any previously set authentication information. + * + * @param gssName The GSS name string. **/ public void setGSSName(String gssName) { @@ -4060,11 +4416,18 @@ public void setGSSName(String gssName) } /** - Sets the environment in which you are running. If guiAvailable is set to true, then prompting may occur during sign-on to display error conditions, to prompt for additional information, or to prompt for change password. If guiAvailable is set to false, then error conditions or missing information will result in exceptions. Applications that are running as IBM i applications or want to control the sign-on user interface may want to run with prompting mode set to false. Prompting mode is set to true by default. -

Note: This property may also be set by specifying 'true' or 'false' in Java system property com.ibm.as400.access.AS400.guiAvailable - @param guiAvailable true to prompt; false otherwise. - @exception PropertyVetoException If any of the registered listeners vetos the property change. - @see SignonHandler + * Sets the environment in which you are running. If guiAvailable is set to true, then prompting may occur during + * sign-on to display error conditions, to prompt for additional information, or to prompt for change password. If + * guiAvailable is set to false, then error conditions or missing information will result in exceptions. + * Applications that are running as IBM i applications or want to control the sign-on user interface may want to run + * with prompting mode set to false. Prompting mode is set to true by default. + *

+ * Note: This property may also be set by specifying 'true' or 'false' in Java system property + * com.ibm.as400.access.AS400.guiAvailable + * + * @param guiAvailable true to prompt; false otherwise. + * @exception PropertyVetoException If any of the registered listeners vetos the property change. + * @see SignonHandler **/ public void setGuiAvailable(boolean guiAvailable) throws PropertyVetoException { @@ -4087,9 +4450,11 @@ public void setGuiAvailable(boolean guiAvailable) throws PropertyVetoException } /** - Sets the Locale used to set the National Language Version (NLV) on the system. Only the COMMAND, PRINT, - and DATABASE services accept an NLV. This method will set the NLV based on a mapping from the Locale object to the NLV. - @param locale The Locale object. + * Sets the Locale used to set the National Language Version (NLV) on the system. Only the COMMAND, PRINT, and + * DATABASE services accept an NLV. This method will set the NLV based on a mapping from the Locale object to the + * NLV. + * + * @param locale The Locale object. **/ public void setLocale(Locale locale) { @@ -4121,10 +4486,11 @@ public void setLocale(Locale locale) } /** - Sets the Locale and a specific National Language Version (NLV) to send to the system. Only the COMMAND, PRINT, - and DATABASE services accept an NLV. - @param locale The Locale object. - @param nlv The NLV. + * Sets the Locale and a specific National Language Version (NLV) to send to the system. Only the COMMAND, PRINT, + * and DATABASE services accept an NLV. + * + * @param locale The Locale object. + * @param nlv The NLV. **/ public void setLocale(Locale locale, String nlv) { @@ -4147,11 +4513,16 @@ public void setLocale(Locale locale, String nlv) } /** - Sets this object to attempt to add the appropriate secondary language library to the library list, when running on the system. - The default is false. Setting the language library will ensure that any system error messages that are returned, will be returned in the appropriate national language for the client locale. If the user profile has insufficient authority to call CHGSYSLIBL, an error entry will appear in the job log, and the Toolbox will disregard the error and proceed normally. -

Note: This property may also be set by specifying 'true' or 'false' in Java system property - com.ibm.as400.access.AS400.mustAddLanguageLibrary - @param mustAddLanguageLibrary true to add language library; false otherwise. + * Sets this object to attempt to add the appropriate secondary language library to the library list, when running + * on the system. The default is false. Setting the language library will ensure that any system error messages that + * are returned, will be returned in the appropriate national language for the client locale. If the user profile + * has insufficient authority to call CHGSYSLIBL, an error entry will appear in the job log, and the Toolbox will + * disregard the error and proceed normally. + *

+ * Note: This property may also be set by specifying 'true' or 'false' in Java system property + * com.ibm.as400.access.AS400.mustAddLanguageLibrary + * + * @param mustAddLanguageLibrary true to add language library; false otherwise. **/ public void setMustAddLanguageLibrary(boolean mustAddLanguageLibrary) { @@ -4166,8 +4537,10 @@ public void setMustAddLanguageLibrary(boolean mustAddLanguageLibrary) } /** - Indicates whether this object will attempt to add the appropriate secondary language library to the library list, when running on the system. - @return true if you have indicated that the secondary language library must be added; false otherwise. + * Indicates whether this object will attempt to add the appropriate secondary language library to the library list, + * when running on the system. + * + * @return true if you have indicated that the secondary language library must be added; false otherwise. **/ public boolean isMustAddLanguageLibrary() { @@ -4177,9 +4550,16 @@ public boolean isMustAddLanguageLibrary() } /** - Sets this object to using sockets. When your Java program runs on the system, some Toolbox classes access data via a call to an API instead of making a socket call to the system. There are minor differences in the behavior of the classes when they use API calls instead of socket calls. If your program is affected by these differences you can force the Toolbox classes to use socket calls instead of API calls by using this method. The default is false. The must use sockets property cannot be changed once a connection to the system has been established. -

Note: This property may also be set by specifying 'true' or 'false' in Java system property com.ibm.as400.access.AS400.mustUseSockets - @param mustUseSockets true to use sockets; false otherwise. + * Sets this object to using sockets. When your Java program runs on the system, some Toolbox classes access data + * via a call to an API instead of making a socket call to the system. There are minor differences in the behavior + * of the classes when they use API calls instead of socket calls. If your program is affected by these differences + * you can force the Toolbox classes to use socket calls instead of API calls by using this method. The default is + * false. The must use sockets property cannot be changed once a connection to the system has been established. + *

+ * Note: This property may also be set by specifying 'true' or 'false' in Java system property + * com.ibm.as400.access.AS400.mustUseSockets + * + * @param mustUseSockets true to use sockets; false otherwise. **/ public void setMustUseSockets(boolean mustUseSockets) { @@ -4193,8 +4573,9 @@ public void setMustUseSockets(boolean mustUseSockets) } /** - Indicates if Internet domain sockets only will be used. - @return true if must use Internet domain sockets only; false otherwise. + * Indicates if Internet domain sockets only will be used. + * + * @return true if must use Internet domain sockets only; false otherwise. **/ public boolean isMustUseNetSockets() { @@ -4203,9 +4584,15 @@ public boolean isMustUseNetSockets() } /** - Sets this object to using Internet domain sockets only. When your Java program runs on the system, some Toolbox classes create UNIX domain socket connections. Using this method forces the Toolbox to only use Internet domain sockets. The default is false. The must use net sockets property cannot be changed once a connection to the system has been established. -

Note: This property may also be set by specifying 'true' or 'false' in Java system property com.ibm.as400.access.AS400.mustUseNetSockets - @param mustUseNetSockets true to use Internet domain sockets only; false otherwise. + * Sets this object to using Internet domain sockets only. When your Java program runs on the system, some Toolbox + * classes create UNIX domain socket connections. Using this method forces the Toolbox to only use Internet domain + * sockets. The default is false. The must use net sockets property cannot be changed once a connection to the + * system has been established. + *

+ * Note: This property may also be set by specifying 'true' or 'false' in Java system property + * com.ibm.as400.access.AS400.mustUseNetSockets + * + * @param mustUseNetSockets true to use Internet domain sockets only; false otherwise. **/ public void setMustUseNetSockets(boolean mustUseNetSockets) { @@ -4219,8 +4606,9 @@ public void setMustUseNetSockets(boolean mustUseNetSockets) } /** - Indicates if only a supplied profile will be used. - @return true if must use a supplied profile only; false otherwise. + * Indicates if only a supplied profile will be used. + * + * @return true if must use a supplied profile only; false otherwise. **/ public boolean isMustUseSuppliedProfile() { @@ -4229,9 +4617,15 @@ public boolean isMustUseSuppliedProfile() } /** - Sets this object to using a supplied profile only. When your Java program runs on the system, the information from the currently signed-on user profile can be used. Using this method prevents the Toolbox from retrieving the current user profile information. The default is false. The must use supplied profile property cannot be changed once a connection to the system has been established. -

Note: This property may also be set by specifying 'true' or 'false' in Java system property com.ibm.as400.access.AS400.mustUseSuppliedProfile - @param mustUseSuppliedProfile true to use a supplied profile only; false otherwise. + * Sets this object to using a supplied profile only. When your Java program runs on the system, the information + * from the currently signed-on user profile can be used. Using this method prevents the Toolbox from retrieving the + * current user profile information. The default is false. The must use supplied profile property cannot be + * changed once a connection to the system has been established. + *

+ * Note: This property may also be set by specifying 'true' or 'false' in Java system property + * com.ibm.as400.access.AS400.mustUseSuppliedProfile + * + * @param mustUseSuppliedProfile true to use a supplied profile only; false otherwise. **/ public void setMustUseSuppliedProfile(boolean mustUseSuppliedProfile) { @@ -4245,10 +4639,14 @@ public void setMustUseSuppliedProfile(boolean mustUseSuppliedProfile) } /** - Sets the password for this object. Only one authentication means (Kerberos ticket, profile token, identity token, or password) can be used at a single time. Using this method will clear any previously set authentication information. - @param password The user profile password. - @deprecated + * Sets the password for this object. Only one authentication means (Kerberos ticket, profile token, identity token, + * or password) can be used at a single time. Using this method will clear any previously set authentication + * information. + * + * @param password The user profile password. + * @deprecated **/ + @Deprecated public void setPassword(String password) { char[] passwordChars = (password == null) ? null : password.toCharArray(); @@ -4261,11 +4659,12 @@ public void setPassword(String password) } } - /** - Sets the password for this object using a char array. - The caller is responsible for clearing the array after the method returns. - Only one authentication means (Kerberos ticket, profile token, identity token, or password) can be used at a single time. Using this method will clear any previously set authentication information. - @param password The user profile password. + /** + * Sets the password for this object using a char array. The caller is responsible for clearing the array after the + * method returns. Only one authentication means (Kerberos ticket, profile token, identity token, or password) can + * be used at a single time. Using this method will clear any previously set authentication information. + * + * @param password The user profile password. **/ public void setPassword(char[] password) { @@ -4281,10 +4680,10 @@ public void setPassword(char[] password) } } - /** - Sets the number of days before password expiration to warn the user. - @param days The number of days before expiration to start the warning. Set to -1 to turn off warning. + * Sets the number of days before password expiration to warn the user. + * + * @param days The number of days before expiration to start the warning. Set to -1 to turn off warning. **/ public static void setPasswordExpirationWarningDays(int days) { @@ -4293,8 +4692,10 @@ public static void setPasswordExpirationWarningDays(int days) } /** - Sets or resets the profile token for this object. Using this method will clear any previously set authentication information. - @param profileToken The profile token. + * Sets or resets the profile token for this object. Using this method will clear any previously set authentication + * information. + * + * @param profileToken The profile token. **/ public void setProfileToken(ProfileTokenCredential profileToken) { @@ -4312,10 +4713,18 @@ public void setProfileToken(ProfileTokenCredential profileToken) } /** - Sets the name and port of the middle-tier machine where the proxy server is running. If this is not set, then the name is retrieved from the com.ibm.as400.access.AS400.proxyServer system property. The ProxyServer must be running on the middle-tier machine. -

The name of the middle-tier machine is ignored in a two-tier environment. If no middle-tier machine is specified, then it is assumed that no middle-tier will be accessed. The name of the middle-tier machine cannot be changed once a connection to this machine has been established. - @param proxyServer The name and port of the proxy server in the format serverName[:port]. If no port is specified, a default will be used. - @exception PropertyVetoException If any of the registered listeners vetos the property change. + * Sets the name and port of the middle-tier machine where the proxy server is running. If this is not set, then the + * name is retrieved from the com.ibm.as400.access.AS400.proxyServer + * system property. The ProxyServer + * must be running on the middle-tier machine. + *

+ * The name of the middle-tier machine is ignored in a two-tier environment. If no middle-tier machine is specified, + * then it is assumed that no middle-tier will be accessed. The name of the middle-tier machine cannot be changed + * once a connection to this machine has been established. + * + * @param proxyServer The name and port of the proxy server in the format serverName[:port]. If no port + * is specified, a default will be used. + * @exception PropertyVetoException If any of the registered listeners vetos the property change. **/ public void setProxyServer(String proxyServer) throws PropertyVetoException { @@ -4344,20 +4753,23 @@ public void setProxyServer(String proxyServer) throws PropertyVetoException } /** - Sets the service port in the service port table for the specified service for this system name. - @param service The name of the service. Valid services are: -

- @param port The port to use for this service. The value {@link #USE_PORT_MAPPER USE_PORT_MAPPER} can be used to specify that the next connection to this service should ask the port mapper server for the port number. + * Sets the service port in the service port table for the specified service for this system name. + * + * @param service The name of the service. Valid services are: + * + * @param port The port to use for this service. The value {@link #USE_PORT_MAPPER USE_PORT_MAPPER} can be used + * to specify that the next connection to this service should ask the port mapper server for the port + * number. **/ public void setServicePort(int service, int port) { @@ -4382,7 +4794,10 @@ public void setServicePort(int service, int port) } /** - Sets the ports in the service port table for all the services for this system name to their default values. This causes the connections to this system name to use the default ports for those services rather than querying the port number through a port mapper connection. The use of this method can reduce the number of connections made to the system. + * Sets the ports in the service port table for all the services for this system name to their default values. This + * causes the connections to this system name to use the default ports for those services rather than querying the + * port number through a port mapper connection. The use of this method can reduce the number of connections made to + * the system. **/ public void setServicePortsToDefault() { @@ -4399,8 +4814,9 @@ public void setServicePortsToDefault() } /** - Indicates if checkboxes should be shown on the sign-on dialog. - @param showCheckboxes true to show checkboxes; false otherwise. + * Indicates if checkboxes should be shown on the sign-on dialog. + * + * @param showCheckboxes true to show checkboxes; false otherwise. **/ public void setShowCheckboxes(boolean showCheckboxes) { @@ -4409,11 +4825,15 @@ public void setShowCheckboxes(boolean showCheckboxes) } /** - Sets the sign-on handler for this AS400 object. The specified handler will be called at runtime if the AS400 object needs to obtain additional signon information. -
By default, an internal AWT-based implementation is used, if no sign-on handler has been statically set via setDefaultSignonHandler(). - @param handler The sign-on handler. Specifying null will reset the default sign-on handler to the internal AWT-based handler. - @see #getSignonHandler - @see #setDefaultSignonHandler + * Sets the sign-on handler for this AS400 object. The specified handler will be called at runtime if the AS400 + * object needs to obtain additional signon information.
+ * By default, an internal AWT-based implementation is used, if no sign-on handler has been statically set via + * setDefaultSignonHandler(). + * + * @param handler The sign-on handler. Specifying null will reset the default sign-on handler to the + * internal AWT-based handler. + * @see #getSignonHandler + * @see #setDefaultSignonHandler **/ public void setSignonHandler(SignonHandler handler) { @@ -4426,13 +4846,16 @@ public void setSignonHandler(SignonHandler handler) } /** - Set the stay-alve interval. When enabled, a request is sent at the specified milliseconds interval to all currently opened - connections to help keep the connections alive. This is sometimes needed to prevent firewalls from dropping stale connections. - The use of this method applies only to connections created after this method is called. This stay-alive functionality - only applies to connections to the following host servers: {@link #COMMAND COMMAND}, {@link #DATABASE DATABASE}, - {@link #DATAQUEUE DATAQUEUE}, {@link #FILE FILE}, and {@link #PRINT PRINT}. - @param milliseconds The number of milliseconds between requests to the server. If set to zero, then this stay-alive - capability will not be used. + * Set the stay-alve interval. When enabled, a request is sent at the specified milliseconds interval to all + * currently opened connections to help keep the connections alive. This is sometimes needed to prevent firewalls + * from dropping stale connections. The use of this method applies only to connections created after this method is + * called. This stay-alive functionality only applies to connections to the following host servers: {@link #COMMAND + * COMMAND}, {@link #DATABASE DATABASE}, {@link #DATAQUEUE DATAQUEUE}, {@link #FILE FILE}, and {@link #PRINT PRINT}. + *

+ * NOTE: NOT YET IMPLEMENTED. + * + * @param milliseconds The number of milliseconds between requests to the server. If set to zero, then this + * stay-alive capability will not be used. **/ public void setStayAlive(long milliseconds) { @@ -4441,8 +4864,10 @@ public void setStayAlive(long milliseconds) } /** - Sets the socket options the IBM Toolbox for Java will set on its client side sockets. The socket properties cannot be changed once a connection to the system has been established. - @param socketProperties The set of socket options to set. The options are copied from this object, not shared. + * Sets the socket options the IBM Toolbox for Java will set on its client side sockets. The socket properties + * cannot be changed once a connection to the system has been established. + * + * @param socketProperties The set of socket options to set. The options are copied from this object, not shared. **/ public void setSocketProperties(SocketProperties socketProperties) { @@ -4450,7 +4875,6 @@ public void setSocketProperties(SocketProperties socketProperties) if (socketProperties == null) throw new NullPointerException("socketProperties"); - if (propertiesFrozen_) { Trace.log(Trace.ERROR, "Cannot set socket properties after connection has been made."); @@ -4460,9 +4884,11 @@ public void setSocketProperties(SocketProperties socketProperties) } /** - Sets the system name for this object. The system name cannot be changed once a connection to the system has been established. - @param systemName The name of the IBM i system. Use localhost to access data locally. - @exception PropertyVetoException If any of the registered listeners vetos the property change. + * Sets the system name for this object. The system name cannot be changed once a connection to the system has been + * established. + * + * @param systemName The name of the IBM i system. Use localhost to access data locally. + * @exception PropertyVetoException If any of the registered listeners vetos the property change. **/ public void setSystemName(String systemName) throws PropertyVetoException { @@ -4498,14 +4924,17 @@ public void setSystemName(String systemName) throws PropertyVetoException } /** - Sets whether the IBM Toolbox for Java uses threads in communication with the host servers. The default is true. - Letting the IBM Toolbox for Java use threads may be beneficial to performance, turning threads off may be necessary - if your application needs to be compliant with the Enterprise Java Beans specification. - The thread used property cannot be changed once a connection to the system has been established. - -

Note: This property may also be set by specifying 'true' or 'false' in Java system property com.ibm.as400.access.AS400.threadUsed - @param useThreads true to use threads; false otherwise. - @exception PropertyVetoException If any of the registered listeners vetos the property change. + * Sets whether the IBM Toolbox for Java uses threads in communication with the host servers. The default is true. + * Letting the IBM Toolbox for Java use threads may be beneficial to performance, turning threads off may be + * necessary if your application needs to be compliant with the Enterprise Java Beans specification. The thread used + * property cannot be changed once a connection to the system has been established. + * + *

+ * Note: This property may also be set by specifying 'true' or 'false' in Java system property + * com.ibm.as400.access.AS400.threadUsed + * + * @param useThreads true to use threads; false otherwise. + * @exception PropertyVetoException If any of the registered listeners vetos the property change. **/ public void setThreadUsed(boolean useThreads) throws PropertyVetoException { @@ -4534,9 +4963,12 @@ public void setThreadUsed(boolean useThreads) throws PropertyVetoException } /** - Sets the indicator for whether the default user is used. The default user is used if a system name is provided, but a user ID is not. If a default user is set for that system, then the default user is used. - @param useDefaultUser The value indicating if the default user should be used. Set to true if default user should be used; false otherwise. The default is true, indicating that the default user is used. - @exception PropertyVetoException If any of the registered listeners vetos the property change. + * Sets the indicator for whether the default user is used. The default user is used if a system name is provided, + * but a user ID is not. If a default user is set for that system, then the default user is used. + * + * @param useDefaultUser The value indicating if the default user should be used. Set to true if default user should + * be used; false otherwise. The default is true, indicating that the default user is used. + * @exception PropertyVetoException If any of the registered listeners vetos the property change. **/ public void setUseDefaultUser(boolean useDefaultUser) throws PropertyVetoException { @@ -4559,10 +4991,15 @@ public void setUseDefaultUser(boolean useDefaultUser) throws PropertyVetoExcepti } /** - Sets the indicator for whether the password cache is used. If password cache is used, then the user would only have to enter password once within a Java virtual machine. The default is to use the cache. -
Unless the application is running in its own private JVM, users are advised to turn off password caching, in order to ensure that another application within the same JVM cannot create a connection using the cached password. - @param usePasswordCache The value indicating whether the password cache should be used. Set to true to use the password cache; false otherwise. - @exception PropertyVetoException If any of the registered listeners vetos the property change. + * Sets the indicator for whether the password cache is used. If password cache is used, then the user would only + * have to enter password once within a Java virtual machine. The default is to use the cache.
+ * Unless the application is running in its own private JVM, users are advised to turn off password caching, in + * order to ensure that another application within the same JVM cannot create a connection using the cached + * password. + * + * @param usePasswordCache The value indicating whether the password cache should be used. Set to true to use the + * password cache; false otherwise. + * @exception PropertyVetoException If any of the registered listeners vetos the property change. **/ public void setUsePasswordCache(boolean usePasswordCache) throws PropertyVetoException { @@ -4585,11 +5022,12 @@ public void setUsePasswordCache(boolean usePasswordCache) throws PropertyVetoExc } /** - Sets the user ID for this object. The user ID cannot be changed once a connection to the system has been established. If this - method is used in conjunction with a Kerberos ticket, profile token, or identity token, the user profile associated with - the authentication token must match this user ID. - @param userId The user profile name. - @exception PropertyVetoException If any of the registered listeners vetos the property change. + * Sets the user ID for this object. The user ID cannot be changed once a connection to the system has been + * established. If this method is used in conjunction with a Kerberos ticket, profile token, or identity token, the + * user profile associated with the authentication token must match this user ID. + * + * @param userId The user profile name. + * @exception PropertyVetoException If any of the registered listeners vetos the property change. **/ public void setUserId(String userId) throws PropertyVetoException { @@ -4716,8 +5154,9 @@ synchronized void signon(boolean keepConnection) throws AS400SecurityException, } /** - Returns the text representation of this AS400 object. - @return The string representing this AS400 object. + * Returns the text representation of this AS400 object. + * + * @return The string representing this AS400 object. **/ public String toString() { return "AS400 (system name: '" + systemName_ + "' user ID: '" + userId_ + "'):" + super.toString(); @@ -4763,13 +5202,18 @@ private static boolean userIdMatchesLocal(String userId, boolean mustUseSupplied } /** - Validates the user ID and password on the system but does not add to the signed-on list. This means that a new - AS400 object instance is created to do the validation. The user ID and system name need to be set before calling this method. -

Note: This will return true if the information is successfully validated. An unsuccessful validation will cause an exception to be thrown, false is never returned. -

Note:If an additional authentication factor has been set in the AS400 object, it is used. - @return true if successful. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. + * Validates the user ID and password on the system but does not add to the signed-on list. This means that a new + * AS400 object instance is created to do the validation. The user ID and system name need to be set before calling + * this method. + *

+ * Note: This will return true if the information is successfully validated. An unsuccessful validation will + * cause an exception to be thrown, false is never returned. + *

+ * Note:If an additional authentication factor has been set in the AS400 object, it is used. + * + * @return true if successful. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. **/ public boolean validateSignon() throws AS400SecurityException, IOException { @@ -4791,17 +5235,22 @@ public boolean validateSignon() throws AS400SecurityException, IOException } /** - Validates the user ID and password on the system but does not add to the signed-on list. This means that a new - AS400 object instance is created to do the validation. - The user ID and system name need to be set before calling this method. -

Note: This will return true if the information is successfully validated. An unsuccessful validation will cause an exception to be thrown, false is never returned. -

Note:If an additional authentication factor has been set in the AS400 object, it is used. - @param password The user profile password to validate. - @return true if successful. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. - @deprecated + * Validates the user ID and password on the system but does not add to the signed-on list. This means that a new + * AS400 object instance is created to do the validation. The user ID and system name need to be set before calling + * this method. + *

+ * Note: This will return true if the information is successfully validated. An unsuccessful validation will + * cause an exception to be thrown, false is never returned. + *

+ * Note:If an additional authentication factor has been set in the AS400 object, it is used. + * + * @param password The user profile password to validate. + * @return true if successful. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. + * @deprecated **/ + @Deprecated public boolean validateSignon(String password) throws AS400SecurityException, IOException { char[] passwordChars = (password == null) ? null : password.toCharArray(); @@ -4815,15 +5264,19 @@ public boolean validateSignon(String password) throws AS400SecurityException, IO } /** - Validates the user ID and password on the system but does not add to the signed-on list. This means that a new - AS400 object instance is created to do the validation. - The user ID and system name need to be set before calling this method. -

Note: This will return true if the information is successfully validated. An unsuccessful validation will cause an exception to be thrown, false is never returned. -

Note:If an additional authentication factor has been set in the AS400 object, it is used. - @param password The user profile password to validate. - @return true if successful. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. + * Validates the user ID and password on the system but does not add to the signed-on list. This means that a new + * AS400 object instance is created to do the validation. The user ID and system name need to be set before calling + * this method. + *

+ * Note: This will return true if the information is successfully validated. An unsuccessful validation will + * cause an exception to be thrown, false is never returned. + *

+ * Note:If an additional authentication factor has been set in the AS400 object, it is used. + * + * @param password The user profile password to validate. + * @return true if successful. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. **/ public boolean validateSignon(char[] password) throws AS400SecurityException, IOException { @@ -4848,19 +5301,24 @@ public boolean validateSignon(char[] password) throws AS400SecurityException, IO } /** - Validates the user ID and password on the system but does not add to the signed-on list. This means that a new - AS400 object instance is created to do the validation. - The system name needs to be set prior to calling this method. -

Note: This will return true if the information is successfully validated. An unsuccessful validation will cause an exception to be thrown, false is never returned. -

Note:If an additional authentication factor has been set in the AS400 object, it is not used. If you want to use an additional authentication factor, - see {@link #validateSignon(String, char[], char[])} - @param userId The user profile name to validate. - @param password The user profile password to validate. - @return true if successful. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. - @deprecated Using a string as a password is insecure - **/ + * Validates the user ID and password on the system but does not add to the signed-on list. This means that a new + * AS400 object instance is created to do the validation. The system name needs to be set prior to calling this + * method. + *

+ * Note: This will return true if the information is successfully validated. An unsuccessful validation will + * cause an exception to be thrown, false is never returned. + *

+ * Note:If an additional authentication factor has been set in the AS400 object, it is not used. If you want + * to use an additional authentication factor, see {@link #validateSignon(String, char[], char[])} + * + * @param userId The user profile name to validate. + * @param password The user profile password to validate. + * @return true if successful. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. + * @deprecated Using a string as a password is insecure + **/ + @Deprecated public boolean validateSignon(String userId, String password) throws AS400SecurityException, IOException { char[] passwordChars = (password == null) ? null : password.toCharArray(); @@ -4873,37 +5331,44 @@ public boolean validateSignon(String userId, String password) throws AS400Securi } } - /** - Validates the user ID and password on the system but does not add to the signed-on list. This means that a new - AS400 object instance is created to do the validation. - The system name needs to be set prior to calling this method. -

Note: This will return true if the information is successfully validated. An unsuccessful validation will cause an exception to be thrown, false is never returned. -

Note:If an additional authentication factor has been set in the AS400 object, it is not used. If you want to use an additional authentication factor, - see {@link #validateSignon(String, char[], char[])} - @param userId The user profile name to validate. - @param password The user profile password to validate. - @return true if successful. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. + /** + * Validates the user ID and password on the system but does not add to the signed-on list. This means that a new + * AS400 object instance is created to do the validation. The system name needs to be set prior to calling this + * method. + *

+ * Note: This will return true if the information is successfully validated. An unsuccessful validation will + * cause an exception to be thrown, false is never returned. + *

+ * Note:If an additional authentication factor has been set in the AS400 object, it is not used. If you want + * to use an additional authentication factor, see {@link #validateSignon(String, char[], char[])} + * + * @param userId The user profile name to validate. + * @param password The user profile password to validate. + * @return true if successful. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. **/ public boolean validateSignon(String userId, char[] password) throws AS400SecurityException, IOException { return validateSignon(userId, password, null); } - /** - Validates the user ID and password on the system but does not add to the signed-on list. This means that a new - AS400 object instance is created to do the validation. - The system name needs to be set prior to calling this method. -

Note: This will return true if the information is successfully validated. An unsuccessful validation will cause an exception to be thrown, false is never returned. - @param userId The user profile name to validate. - @param password The user profile password to validate. - @param additionalAuthenticationFactor Additional authentication factor (or null if not providing one). - @return true if successful. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. + /** + * Validates the user ID and password on the system but does not add to the signed-on list. This means that a new + * AS400 object instance is created to do the validation. The system name needs to be set prior to calling this + * method. + *

+ * Note: This will return true if the information is successfully validated. An unsuccessful validation will + * cause an exception to be thrown, false is never returned. + * + * @param userId The user profile name to validate. + * @param password The user profile password to validate. + * @param additionalAuthFactor Additional authentication factor (or null if not providing one). + * @return true if successful. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. **/ - public boolean validateSignon(String userId, char[] password, char[] additionalAuthenticationFactor) throws AS400SecurityException, IOException + public boolean validateSignon(String userId, char[] password, char[] additionalAuthFactor) throws AS400SecurityException, IOException { if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Validating signon, password and additional factor, user ID: '" + userId + "'"); @@ -4927,12 +5392,12 @@ public boolean validateSignon(String userId, char[] password, char[] additionalA userId = userId.toUpperCase(Locale.ENGLISH); if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "This system locale is Turkish, userId.toUpperCase(Locale.ENGLISH)"); } - return validateSignon(true, userId.toUpperCase(), tempVault, additionalAuthenticationFactor); + return validateSignon(true, userId.toUpperCase(), tempVault, additionalAuthFactor); } // Internal version of validate sign-on; takes checked user ID and twiddled password bytes. // If the signon info is not valid, an exception is thrown. - private boolean validateSignon(boolean useNewInstance, String userId, CredentialVault pwVault, char[] additionalAuthenticationFactor) throws AS400SecurityException, IOException + private boolean validateSignon(boolean useNewInstance, String userId, CredentialVault pwVault, char[] additionalAuthFactor) throws AS400SecurityException, IOException { // Use a new instance when system, userid, and credentials are not part of this // instance of AS400 class; otherwise, use this instance. @@ -4940,7 +5405,7 @@ private boolean validateSignon(boolean useNewInstance, String userId, Credential { if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Creating temporary connection for validating signon info."); - try (AS400 validationSystem = new AS400(systemName_, userId, pwVault, additionalAuthenticationFactor)) + try (AS400 validationSystem = new AS400(systemName_, userId, pwVault, additionalAuthFactor)) { validationSystem.proxyServer_ = proxyServer_; // proxyClientConnection_ is not needed. @@ -5003,8 +5468,9 @@ void forcePrompt() private int bidiStringType = BidiStringType.DEFAULT; /** - * Sets bidi string type of the connection. - * See BidiStringType for more information and valid values. + * Sets bidi string type of the connection. See BidiStringType for more + * information and valid values. + * * @param bidiStringType bidi string type to use for the connection. */ public void setBidiStringType(int bidiStringType){ @@ -5012,8 +5478,9 @@ public void setBidiStringType(int bidiStringType){ } /** - * Returns bidi string type of the connection. - * See BidiStringType for more information and valid values. + * Returns bidi string type of the connection. See BidiStringType for more + * information and valid values. + * * @return The bidi string type of the connection. */ public int getBidiStringType(){ @@ -5044,6 +5511,11 @@ void setSignonInfo(int serverCCSID, int serverVersion, String userId) ccsid_ = signonInfo_.serverCCSID; } + /** + * Return whether default locale is Turkish. + * + * @return true if Turkish; otherwise, false. + */ public static boolean isTurkish() { Locale defaultLocale = Locale.getDefault(); @@ -5052,22 +5524,31 @@ public static boolean isTurkish() return (defaultLocale.equals(Turkishlocale) ) ? true : false; } + /** + * Returns the timeout value when attempting to validate the sign on information. + * + * @return The timeout value in milliseconds. + */ public int getvalidateSignonTimeOut() { return validateSignonTimeOut_; } + /** + * Set the the timeout value when when attempting to validate the sign on information. + * + * @param validateSignonTimeOut The timeout value in milliseconds. + */ public void setvalidateSignonTimeOut(int validateSignonTimeOut) { validateSignonTimeOut_ = validateSignonTimeOut; } /** * Password level - * @return -1 - Not remote method, such as proxy method. - * 0, 1 - password type is DES - * 2, 3 - password type is SHA-1 - * 4 - password type is SHA-512 - * @throws AS400SecurityException If a security or authority error occurs. - * @throws IOException If an error occurs while communicating with the system. + * + * @return -1 - Not remote method, such as proxy method. 0, 1 - password type is DES 2, 3 - password type is SHA-1 4 + * - password type is SHA-512 + * @throws AS400SecurityException If a security or authority error occurs. + * @throws IOException If an error occurs while communicating with the system. */ public int passwordLevel() throws AS400SecurityException, IOException { @@ -5085,9 +5566,10 @@ public int passwordLevel() throws AS400SecurityException, IOException } /** - *

This method is functionally equivalent to the resetAllServices() method. - @see #resetAllServices - **/ + * This method is functionally equivalent to the resetAllServices() method. + * + * @see #resetAllServices + **/ @Override public void close() { // resetAllServices() ensures that HOSTCNN is disconnected from this AS400. @@ -5106,9 +5588,10 @@ private void ensureSecureInstance() } /** - Returns true if host server communications is performed over a secure channel. - @return true if communications is done over secure channel; otherwise false. - **/ + * Returns true if host server communications is performed over a secure channel. + * + * @return true if communications is done over secure channel; otherwise false. + **/ public boolean isSecure() { return (this instanceof SecureAS400); } @@ -5118,12 +5601,15 @@ public boolean isSecure() { // ======== START ================= /** - Returns the key ring class name used for SSL communications with the system. The - class com.ibm.as400.access.KeyRing is the default and will be returned if not overridden. -

Note:An exception will be thrown if the AS400 object is not an instance of SecureAS400. - @return The key ring class name. - @deprecated - **/ + * Returns the key ring class name used for SSL communications with the system. The class + * com.ibm.as400.access.KeyRing is the default and will be returned if not overridden. + *

+ * Note:An exception will be thrown if the AS400 object is not an instance of SecureAS400. + * + * @return The key ring class name. + * @deprecated + **/ + @Deprecated public String getKeyRingName() { ensureSecureInstance(); @@ -5133,10 +5619,12 @@ public String getKeyRingName() } /** - Returns the proxy encryption mode. The proxy encryption mode specifies which portions of the communications - between the client, proxy server, and IBM i system are encrypted. -

Note:An exception will be thrown if the AS400 object is not an instance of SecureAS400. - @return The proxy encryption mode. + * Returns the proxy encryption mode. The proxy encryption mode specifies which portions of the communications + * between the client, proxy server, and IBM i system are encrypted. + *

+ * Note:An exception will be thrown if the AS400 object is not an instance of SecureAS400. + * + * @return The proxy encryption mode. **/ public int getProxyEncryptionMode() { @@ -5147,11 +5635,13 @@ public int getProxyEncryptionMode() } /** - Sets the key ring class name used for SSL communications with the system. - This method is no longer supported because sslight is not longer supported. -

Note:An exception will be thrown if the AS400 object is not an instance of SecureAS400. - @param keyRingName The key ring class name. - @exception PropertyVetoException If any of the registered listeners vetos the property change. + * Sets the key ring class name used for SSL communications with the system. This method is no longer supported + * because sslight is not longer supported. + *

+ * Note:An exception will be thrown if the AS400 object is not an instance of SecureAS400. + * + * @param keyRingName The key ring class name. + * @exception PropertyVetoException If any of the registered listeners vetos the property change. **/ public void setKeyRingName(String keyRingName) throws PropertyVetoException { @@ -5162,12 +5652,14 @@ public void setKeyRingName(String keyRingName) throws PropertyVetoException } /** - Sets the key ring class name used for SSL communications with the system. - This method is no longer available since support for sslight has been removed. -

Note:An exception will be thrown if the AS400 object is not an instance of SecureAS400. - @param keyRingName The key ring class name. - @param keyRingPassword The password for the key ring class. - @exception PropertyVetoException If any of the registered listeners vetos the property change. + * Sets the key ring class name used for SSL communications with the system. This method is no longer available since + * support for sslight has been removed. + *

+ * Note:An exception will be thrown if the AS400 object is not an instance of SecureAS400. + * + * @param keyRingName The key ring class name. + * @param keyRingPassword The password for the key ring class. + * @exception PropertyVetoException If any of the registered listeners vetos the property change. **/ public void setKeyRingName(String keyRingName, String keyRingPassword) throws PropertyVetoException { @@ -5178,11 +5670,14 @@ public void setKeyRingName(String keyRingName, String keyRingPassword) throws Pr } /** - Sets the key ring password used for SSL communications with the system. -

Note:An exception will be thrown if the AS400 object is not an instance of SecureAS400. - @param keyRingPassword The password for the key ring class. - @deprecated + * Sets the key ring password used for SSL communications with the system. + *

+ * Note:An exception will be thrown if the AS400 object is not an instance of SecureAS400. + * + * @param keyRingPassword The password for the key ring class. + * @deprecated **/ + @Deprecated public void setKeyRingPassword(String keyRingPassword) { ensureSecureInstance(); @@ -5192,14 +5687,18 @@ public void setKeyRingPassword(String keyRingPassword) } /** - Sets the proxy encryption mode. The proxy encryption mode specifies which portions of the communications between the client, proxy server, and IBM i system are encrypted. The default is to encrypt all communications. This value is ignored if a proxy server is not used. -
Valid proxy encryption modes are: -
{@link #CLIENT_TO_PROXY_SERVER CLIENT_TO_PROXY_SERVER} - encrypt between client and proxy server. -
{@link #PROXY_SERVER_TO_SERVER PROXY_SERVER_TO_SERVER} - encrypt between proxy server and IBM i system. -
{@link #CLIENT_TO_SERVER CLIENT_TO_SERVER} - encrypt both portions of connection. -

Note:An exception will be thrown if the AS400 object is not an instance of SecureAS400. - @param proxyEncryptionMode The proxy encryption mode. - @exception PropertyVetoException If any of the registered listeners vetos the property change. + * Sets the proxy encryption mode. The proxy encryption mode specifies which portions of the communications between + * the client, proxy server, and IBM i system are encrypted. The default is to encrypt all communications. This value + * is ignored if a proxy server is not used.
+ * Valid proxy encryption modes are:
+ * {@link #CLIENT_TO_PROXY_SERVER CLIENT_TO_PROXY_SERVER} - encrypt between client and proxy server.
+ * {@link #PROXY_SERVER_TO_SERVER PROXY_SERVER_TO_SERVER} - encrypt between proxy server and IBM i system.
+ * {@link #CLIENT_TO_SERVER CLIENT_TO_SERVER} - encrypt both portions of connection. + *

+ * Note:An exception will be thrown if the AS400 object is not an instance of SecureAS400. + * + * @param proxyEncryptionMode The proxy encryption mode. + * @exception PropertyVetoException If any of the registered listeners vetos the property change. **/ public void setProxyEncryptionMode(int proxyEncryptionMode) throws PropertyVetoException { @@ -5232,9 +5731,11 @@ public void setProxyEncryptionMode(int proxyEncryptionMode) throws PropertyVetoE } /** - Set list of cipher suites. -

Note:An exception will be thrown if the AS400 object is not an instance of SecureAS400. - @param suites Array of cipher suites. + * Set list of cipher suites. + *

+ * Note:An exception will be thrown if the AS400 object is not an instance of SecureAS400. + * + * @param suites Array of cipher suites. **/ public void setEnabledCipherSuites(String[] suites) { diff --git a/src/main/java/com/ibm/as400/access/AS400GenAuthTknDS.java b/src/main/java/com/ibm/as400/access/AS400GenAuthTknDS.java index 9e95e757e..bfa782cf3 100644 --- a/src/main/java/com/ibm/as400/access/AS400GenAuthTknDS.java +++ b/src/main/java/com/ibm/as400/access/AS400GenAuthTknDS.java @@ -19,9 +19,14 @@ // The AS400GenAuthTknDS class represents the data stream for the 'Generate authentication token' request. class AS400GenAuthTknDS extends ClientAccessDataStream { - AS400GenAuthTknDS(byte[] userIDbytes, byte[] authenticationBytes, int byteType, int profileTokenType, int profileTokenTimeout, int serverLevel) + AS400GenAuthTknDS(byte[] userIDbytes, byte[] authenticationBytes, int authScheme, int profileTokenType, int profileTokenTimeout, int serverLevel, + byte[] addAuthFactor) { - super(new byte[45 + authenticationBytes.length + ((userIDbytes == null || byteType == 1|| byteType ==2)?0:16) + (serverLevel < 5 ? 0 : 7)]); //@AI8C + super(new byte[45 + authenticationBytes.length + + ((userIDbytes == null || authScheme == 1|| authScheme ==2) ? 0:16) + + (serverLevel < 5 ? 0 : 7) + + ((serverLevel >= 18 && null != addAuthFactor && 0 < addAuthFactor.length) ? addAuthFactor.length + 10: 0) + ]); setLength(data_.length); // setHeaderID(0x0000); @@ -32,25 +37,24 @@ class AS400GenAuthTknDS extends ClientAccessDataStream setReqRepID(0x7007); // Type of authentication bytes. - //@AF6A Start - if (byteType == AS400.AUTHENTICATION_SCHEME_IDENTITY_TOKEN) + if (authScheme == AS400.AUTHENTICATION_SCHEME_IDENTITY_TOKEN) data_[20] = (byte)0x06; else data_[20] = (byte)0x02; - if (byteType == AS400.AUTHENTICATION_SCHEME_GSS_TOKEN) + if (authScheme == AS400.AUTHENTICATION_SCHEME_GSS_TOKEN) data_[20] = (byte)0x05; - if (byteType == AS400.AUTHENTICATION_SCHEME_PASSWORD) { - if (authenticationBytes.length == 8) { + if (authScheme == AS400.AUTHENTICATION_SCHEME_PASSWORD) + { + if (authenticationBytes.length == 8) data_[20] = (byte)0x01; - } else if (authenticationBytes.length == 20) { + else if (authenticationBytes.length == 20) data_[20] = (byte)0x03; - } else { + else data_[20] = (byte)0x07; - } - }//@AF6A End - //data_[20] = (byteType == AS400.AUTHENTICATION_SCHEME_PASSWORD) ? (authenticationBytes.length == 8) ? (byte)0x01 : (byte)0x03 : (byteType == AS400.AUTHENTICATION_SCHEME_GSS_TOKEN) ? (byte)0x05 : (byteType == AS400.AUTHENTICATION_SCHEME_IDENTITY_TOKEN) ? (byte)0x06 : (byte)0x02; //@AF6D + } + // Return type, 0x01 = profile token. data_[21] = 0x01; @@ -59,7 +63,7 @@ class AS400GenAuthTknDS extends ClientAccessDataStream set16bit(0x1116, 26); data_[28] = (byte)(0xF0 | profileTokenType); - // Experation interval. + // Expiration interval. set32bit(10, 29); set16bit(0x1117, 33); set32bit(profileTokenTimeout, 35); @@ -68,30 +72,32 @@ class AS400GenAuthTknDS extends ClientAccessDataStream // LL set32bit(6 + authenticationBytes.length, 39); // CP - if (byteType == 0) - { + if (authScheme == 0) set16bit(0x1105, 43); - } else - { set16bit(0x1115, 43); - } + // Data. System.arraycopy(authenticationBytes, 0, data_, 45, authenticationBytes.length); + + int offset = 45 + authenticationBytes.length; - if (userIDbytes != null && byteType != 1 && byteType != 2) //@AI8C + if (userIDbytes != null && authScheme != 1 && authScheme != 2) { // Set user ID info. // LL - set32bit(16, 45 + authenticationBytes.length); + set32bit(16, offset); // CP - set16bit(0x1104, 49 + authenticationBytes.length); + set16bit(0x1104, offset + 4); // EBCDIC user ID. - System.arraycopy(userIDbytes, 0, data_, 51 + authenticationBytes.length, 10); + System.arraycopy(userIDbytes, 0, data_, offset + 6, 10); + + offset += 6 + 10; } + + if (serverLevel >= 5) { - int offset = 45 + authenticationBytes.length + ((userIDbytes == null || byteType == 1|| byteType ==2) ? 0 : 16); //@AI8C // Set return error messages. // LL set32bit(7, offset); @@ -99,9 +105,29 @@ class AS400GenAuthTknDS extends ClientAccessDataStream set16bit(0x1128, offset + 4); // Data. data_[offset + 6] = 0x01; + + offset += 6 + 1; + } + + if (serverLevel >= 18) + { + if (null != addAuthFactor && 0 < addAuthFactor.length) + { + // LL + set32bit(addAuthFactor.length + 4 + 2 + 4, offset); + // CP + set16bit(0x112F, offset + 4); + // CCSID + set32bit(1208, offset + 6); + // data + System.arraycopy(addAuthFactor, 0, data_, offset + 10, addAuthFactor.length); + + offset += 10 + addAuthFactor.length; + } } } + @Override void write(OutputStream out) throws IOException { if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Sending generate authentication token request..."); diff --git a/src/main/java/com/ibm/as400/access/AS400ImplRemote.java b/src/main/java/com/ibm/as400/access/AS400ImplRemote.java index 98baa52f8..59a9d95a2 100644 --- a/src/main/java/com/ibm/as400/access/AS400ImplRemote.java +++ b/src/main/java/com/ibm/as400/access/AS400ImplRemote.java @@ -29,6 +29,7 @@ import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; @@ -171,11 +172,9 @@ public class AS400ImplRemote implements AS400Impl // hostcnn server client seed, held from hostcnn connection until hostcnn disconnect. private byte[] hostcnn_clientSeed_; - // Additional authentication factor. We have to hold on to it because it may be timed. - private char[] additionalAuthFactor_; + // Additional authentication factor. We have to hold on to it because it may be timed, and thus can be reused. + private byte[] additionalAuthFactor_; - private int UserHandle2_ = UNINITIALIZED; - private static final String CLASSNAME = "com.ibm.as400.access.AS400ImplRemote"; static { @@ -561,7 +560,8 @@ else if (passwordLevel_ < 4) ChangePasswordReq chgReq = new ChangePasswordReq(userIdEbcdic, encryptedPassword, oldProtected, oldPassword.length * 2, - newProtected, newPassword.length * 2, serverLevel_, additionalAuthenticationFactor); + newProtected, newPassword.length * 2, serverLevel_, + (additionalAuthenticationFactor != null ? (new String(additionalAuthenticationFactor)).getBytes(StandardCharsets.UTF_8) : null)); ChangePasswordRep chgRep = (ChangePasswordRep) signonServer_.sendAndReceive(chgReq); int rc = chgRep.getRC(); if (rc == 0) @@ -644,68 +644,103 @@ public Socket connectToPort(int port, boolean forceNonLocalhost) throws AS400Sec // @SAA Create user handle for the connection public int createUserHandle() throws AS400SecurityException, IOException { - if (userHandle_ != UNINITIALIZED && credVault_.getType() != AS400.AUTHENTICATION_SCHEME_GSS_TOKEN) + if (userHandle_ != UNINITIALIZED) return userHandle_; - - if (credVault_.getType() == AS400.AUTHENTICATION_SCHEME_GSS_TOKEN) - return createUserHandle2(); - - ClientAccessDataStream ds = null; - int UserHandle = UNINITIALIZED; + + int authScheme = credVault_.getType(); + + if (authScheme != AS400.AUTHENTICATION_SCHEME_GSS_TOKEN && authScheme != AS400.AUTHENTICATION_SCHEME_PASSWORD) + return UNINITIALIZED; - AS400Server connectedServer = getConnectedServer(new int[] { AS400.FILE }); - if (connectedServer != null) + // Do not want to create more than one user handle + synchronized (this) { - byte[] ClientSeed = BinaryConverter.longToByteArray(System.currentTimeMillis()); - byte[] ServerSeed = null; - try - { - IFSUserHandleSeedReq req = new IFSUserHandleSeedReq(ClientSeed); - ds = (ClientAccessDataStream) connectedServer.sendAndReceive(req); - } - catch (InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted"); - InterruptedIOException throwException = new InterruptedIOException( e.getMessage()); - throwException.initCause(e); - throw throwException; - } + if (userHandle_ != UNINITIALIZED) + return userHandle_; + + AS400Server connectedServer = getConnectedServer(new int[] { AS400.FILE }); + if (connectedServer == null) + return UNINITIALIZED; - // Verify that we got a handle back. + ClientAccessDataStream ds = null; int rc = 0; - if (ds instanceof IFSUserHandleSeedRep) - ServerSeed = ((IFSUserHandleSeedRep) ds).getSeed(); - else if (ds instanceof IFSReturnCodeRep) + + if (authScheme == AS400.AUTHENTICATION_SCHEME_GSS_TOKEN) { - rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc != IFSReturnCodeRep.SUCCESS) - Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); - throw new ExtendedIOException(rc); + try + { + byte[] authenticationBytes = (gssCredential_ == null) + ? TokenManager.getGSSToken(systemName_, gssName_) + : TokenManager2.getGSSToken(systemName_, gssCredential_); + + IFSUserHandle2Req req = new IFSUserHandle2Req(authenticationBytes, aafIndicator_ ? additionalAuthFactor_ : null); + ds = (ClientAccessDataStream) connectedServer.sendAndReceive(req); + } + catch (InterruptedException e) + { + Trace.log(Trace.ERROR, "Interrupted"); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; + } + catch (Throwable e) { + Trace.log(Trace.ERROR, "Error retrieving GSSToken:", e); + throw new AS400SecurityException(AS400SecurityException.KERBEROS_TICKET_NOT_VALID_RETRIEVE, e); + } } else { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", ds.getReqRepID()); - throw new InternalErrorException(Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); + // Password authentication scheme + + byte[] ClientSeed = BinaryConverter.longToByteArray(System.currentTimeMillis()); + byte[] ServerSeed = null; + try + { + IFSUserHandleSeedReq req = new IFSUserHandleSeedReq(ClientSeed); + ds = (ClientAccessDataStream) connectedServer.sendAndReceive(req); + } + catch (InterruptedException e) + { + Trace.log(Trace.ERROR, "Interrupted"); + InterruptedIOException throwException = new InterruptedIOException( e.getMessage()); + throwException.initCause(e); + throw throwException; + } + + // Verify that we got a handle back. + if (ds instanceof IFSUserHandleSeedRep) + ServerSeed = ((IFSUserHandleSeedRep) ds).getSeed(); + else if (ds instanceof IFSReturnCodeRep) + { + rc = ((IFSReturnCodeRep) ds).getReturnCode(); + if (rc != IFSReturnCodeRep.SUCCESS) Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); + throw new ExtendedIOException(rc); + } + else + { + // Unknown data stream. + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.getReqRepID()); + throw new InternalErrorException(Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); + } + + rc = 0; + ds = null; + byte[] userIDbytes = SignonConverter.stringToByteArray(userId_); + byte[] encryptedPassword = getPassword(ClientSeed, ServerSeed); + IFSCreateUserHandlerReq req = new IFSCreateUserHandlerReq(userIDbytes, encryptedPassword, aafIndicator_ ? additionalAuthFactor_ : null); + + try { + ds = (ClientAccessDataStream) connectedServer.sendAndReceive(req); + } + catch (InterruptedException e) + { + Trace.log(Trace.ERROR, "Interrupted"); + InterruptedIOException throwException = new InterruptedIOException( e.getMessage()); + throwException.initCause(e); + throw throwException; + } } - - rc = 0; - ds = null; - byte[] userIDbytes = SignonConverter.stringToByteArray(userId_); - byte[] encryptedPassword = getPassword(ClientSeed, ServerSeed); - IFSCreateUserHandlerReq req = new IFSCreateUserHandlerReq(userIDbytes, encryptedPassword); - try { - ds = (ClientAccessDataStream) connectedServer.sendAndReceive(req); - } - catch (InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted"); - InterruptedIOException throwException = new InterruptedIOException( e.getMessage()); - throwException.initCause(e); - throw throwException; - } - // Verify the reply. if (ds instanceof IFSCreateUserHandleRep) { @@ -715,13 +750,12 @@ else if (ds instanceof IFSReturnCodeRep) Trace.log(Trace.ERROR, "IFSCreateUserHandleRep return code", rc); throw new ExtendedIOException(rc); } - UserHandle = ((IFSCreateUserHandleRep) ds).getHandle(); + setUserHandle(((IFSCreateUserHandleRep) ds).getHandle()); } else if (ds instanceof IFSReturnCodeRep) { rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc != IFSReturnCodeRep.SUCCESS) - Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); + if (rc != IFSReturnCodeRep.SUCCESS) Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); throw new ExtendedIOException(rc); } else @@ -732,8 +766,7 @@ else if (ds instanceof IFSReturnCodeRep) } } - setUserHandle(UserHandle); - return UserHandle; + return userHandle_; } public int getUserHandle() { @@ -879,7 +912,6 @@ private void fireConnectEvent(boolean connect, int service) @Override public void generateProfileToken(ProfileTokenCredential profileToken, String userIdentity) throws AS400SecurityException, IOException { - // TODO AMRA - profile tokens via hostcnn signonConnect(); try @@ -940,11 +972,10 @@ public void generateProfileToken(ProfileTokenCredential profileToken, String use } } - // Flow the generate profile token datastream. + @Override public void generateProfileToken(ProfileTokenCredential profileToken, String userId, CredentialVault vault, String gssName) throws AS400SecurityException, IOException, InterruptedException { - // TODO AMRA - profile tokens via hostcnn signonConnect(); try @@ -1079,10 +1110,13 @@ else if (passwordLevel_ < 4) authenticationBytes = generateSha512Substitute(userId_, token, serverSeed_, clientSeed_, sequence); } } + + byte[] aaf = aafIndicator_ ? additionalAuthFactor_ : null; AS400GenAuthTknDS req = new AS400GenAuthTknDS(userIdEbcdic, authenticationBytes, authScheme, profileToken.getTokenType(), - profileToken.getTimeoutInterval(), serverLevel_); + profileToken.getTimeoutInterval(), serverLevel_, aaf); + CredentialVault.clearArray(authenticationBytes); AS400GenAuthTknReplyDS rep = (AS400GenAuthTknReplyDS) signonServer_.sendAndReceive(req); req.clear(); @@ -1403,18 +1437,15 @@ private String obtainJobIdForConnection(byte[] jobBytes) throws UnsupportedEncod return jobString; } - public AS400Server getConnection(int service, boolean forceNewConnection) - throws AS400SecurityException, IOException { + public AS400Server getConnection(int service, boolean forceNewConnection) throws AS400SecurityException, IOException { return getConnection(service, forceNewConnection, false /*Skip signon server */); } - AS400Server getConnection(int service, boolean forceNewConnection, - boolean skipSignonServer) throws AS400SecurityException, IOException { + AS400Server getConnection(int service, boolean forceNewConnection, boolean skipSignonServer) throws AS400SecurityException, IOException { return getConnection(service, -1, forceNewConnection, skipSignonServer); } - synchronized AS400Server getConnection(int service, int overridePort, boolean forceNewConnection, - boolean skipSignonServer) throws AS400SecurityException, IOException + synchronized AS400Server getConnection(int service, int overridePort, boolean forceNewConnection, boolean skipSignonServer) throws AS400SecurityException, IOException { if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Handling request for host server job connection: " + AS400.getServerName(service)); @@ -1539,6 +1570,7 @@ synchronized AS400Server getConnection(int service, int overridePort, boolean fo Trace.log(Trace.DIAGNOSTIC, " Server seed:", serverSeed); Trace.log(Trace.DIAGNOSTIC, " Encrypted password:", ddmSubstitutePassword); } + byte[] iaspBytes = null; if (ddmRDB_ != null) { @@ -1546,8 +1578,10 @@ synchronized AS400Server getConnection(int service, int overridePort, boolean fo iaspBytes = text18.toBytes(ddmRDB_); } + byte[] aaf = aafIndicator_ ? additionalAuthFactor_ : null; + ClassDecoupler.connectDDMPhase2(outStream, inStream, userIDbytes, ddmSubstitutePassword, iaspBytes, - authScheme, ddmRDB_, systemName_, connectionID); + authScheme, ddmRDB_, systemName_, connectionID, aaf); } else { @@ -2351,11 +2385,65 @@ else if (service == AS400.HOSTCNN) } private SignonPingReq signonPingRequest_; - private SignonPingReq hostcnnPingRequest_; private IFSPingReq ifsPingRequest_; private static final int NO_PRIOR_SERVICE = -1; private int priorService_ = NO_PRIOR_SERVICE; + + private boolean doPingRequest(AS400Server connectedServer, boolean setPriorService) throws IOException, InterruptedException + { + int service = connectedServer.getService(); + + if (service == AS400.FILE) + { + // a dummy request, just to get a reply + if (ifsPingRequest_ == null) + ifsPingRequest_ = new IFSPingReq(); + + // We expect to get back a reply indicating "request not supported". + DataStream reply = connectedServer.sendAndReceive(ifsPingRequest_); + + if (DEBUG) + { + // Sanity-check the reply. + if (reply instanceof IFSReturnCodeRep) + { + int returnCode = ((IFSReturnCodeRep) reply).getReturnCode(); + // We expect the return code to indicate REQUEST_NOT_SUPPORTED. + // That sort of error doesn't clutter the job log with error entries. + if (returnCode != IFSReturnCodeRep.REQUEST_NOT_SUPPORTED && Trace.traceOn_) + Trace.log(Trace.DIAGNOSTIC, "Ping of File Server failed with unexpected return code " + returnCode); + } + else + Trace.log(Trace.WARNING, "Unexpected IFS reply datastream received.", reply.data_); + } + } + else if (service == AS400.RECORDACCESS) + { + // If all we have is a connection to the DDM Server, simply return true. + // We don't have a way to ping the DDM server without creating an error entry in the job log. + } + else + { + // Only for common servers that support signon ping request + + // To reliably detect a connection is still up, we need to + // send a payload and do a receive. Just sending and discarding reply will not detect broken pipe! + + if (signonPingRequest_ == null) + signonPingRequest_ = new SignonPingReq(12345); + + connectedServer.sendAndReceive(signonPingRequest_); + } + + if (setPriorService) + priorService_ = (service != AS400.RECORDACCESS) ? service : NO_PRIOR_SERVICE; + + // Note that an exception will be thrown if not connected. + return true; + } + + // Check connection's current status. @Override public boolean isConnectionAlive() @@ -2407,20 +2495,9 @@ public boolean isConnectionAlive() AS400.DATABASE, AS400.PRINT, AS400.DATAQUEUE, AS400.CENTRAL }); } - // If we have a connection to a "common" server, send the ping request. // If no exception gets thrown, report that the connection is alive. if (connectedServer != null) - { - // the above services all support "ping" - if (signonPingRequest_ == null) - signonPingRequest_ = new SignonPingReq(); - - connectedServer.sendAndDiscardReply(signonPingRequest_); - - // If no exception was thrown, then the ping succeeded. - isAlive = true; - priorService_ = connectedServer.getService(); - } + isAlive = doPingRequest(connectedServer, true); // If we have a connection to the File Server, send the ping request. // Then if a reply comes back, swallow the "invalid request" error and @@ -2428,35 +2505,8 @@ public boolean isConnectionAlive() if (connectedServer == null) { connectedServer = getConnectedServer(new int[] { AS400.FILE }); - if (connectedServer != null) - { - // a dummy request, just to get a reply - if (ifsPingRequest_ == null) - ifsPingRequest_ = new IFSPingReq(); - - // We expect to get back a reply indicating "request not supported". - DataStream reply = connectedServer.sendAndReceive(ifsPingRequest_); - // If no exception was thrown, then the ping succeeded. - - isAlive = true; - priorService_ = connectedServer.getService(); - - if (DEBUG) - { - // Sanity-check the reply. - if (reply instanceof IFSReturnCodeRep) - { - int returnCode = ((IFSReturnCodeRep) reply).getReturnCode(); - // We expect the return code to indicate REQUEST_NOT_SUPPORTED. - // That sort of error doesn't clutter the job log with error entries. - if (returnCode != IFSReturnCodeRep.REQUEST_NOT_SUPPORTED && Trace.traceOn_) - Trace.log(Trace.DIAGNOSTIC, "Ping of File Server failed with unexpected return code " + returnCode); - } - else - Trace.log(Trace.WARNING, "Unexpected IFS reply datastream received.", reply.data_); - } - } + isAlive = doPingRequest(connectedServer, true); } // If all we have is a connection to the DDM Server, simply return true. @@ -2466,8 +2516,7 @@ public boolean isConnectionAlive() { if (isConnected(AS400.RECORDACCESS)) { - Trace.log(Trace.DIAGNOSTIC, - "For the RECORDACCESS service, isConnectionAlive() defaults to the behavior of isConnected()."); + Trace.log(Trace.DIAGNOSTIC, "For the RECORDACCESS service, isConnectionAlive() defaults to the behavior of isConnected()."); isAlive = true; } @@ -2476,8 +2525,7 @@ public boolean isConnectionAlive() } catch (Exception e) { - if (Trace.traceOn_) - Trace.log(Trace.DIAGNOSTIC, e); + if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, e); isAlive = false; } @@ -2516,85 +2564,12 @@ public boolean isConnectionAlive(int service) // If we have a connection to the specified service, send the ping request. // If no exception gets thrown, report that the connection is alive. - if (connectedServer != null) - { - if (service == AS400.RECORDACCESS) - { - // Special handling for the DDM Server. - - // For the DDM Server, simply return true. - // We don't have a way to ping the DDM server without creating an - // error entry in the host server's job log. - - Trace.log(Trace.DIAGNOSTIC, - "For the RECORDACCESS service, isConnectionAlive() defaults to the behavior of isConnected()."); - isAlive = true; - } - else if (service == AS400.FILE) - { - // Special handling for the File Server. - - // a dummy request, just to get a reply - if (ifsPingRequest_ == null) - ifsPingRequest_ = new IFSPingReq(); - - // We expect to get back a reply indicating "request not supported". - DataStream reply = connectedServer.sendAndReceive(ifsPingRequest_); - // If no exception was thrown, then the ping succeeded. - - isAlive = true; - - if (DEBUG) - { - // Sanity-check the reply. - if (reply instanceof IFSReturnCodeRep) - { - int returnCode = ((IFSReturnCodeRep) reply).getReturnCode(); - // We expect the return code to indicate REQUEST_NOT_SUPPORTED. - // That sort of error doesn't clutter the job log with error - // entries. - if (returnCode != IFSReturnCodeRep.REQUEST_NOT_SUPPORTED && Trace.traceOn_) - Trace.log(Trace.DIAGNOSTIC, - "Ping of File Server failed with unexpected return code " + returnCode); - } - else - Trace.log(Trace.WARNING, "Unexpected IFS reply datastream received.", reply.data_); - } - } - else if (service == AS400.HOSTCNN) - { - // TODO maybe should be the default for all isAlive tests? - - // To reliably detect a connection is still up, we need to - // to send a payload and do a receive. - - // It's a "common service", which will accept a Signon Ping Request. - if (hostcnnPingRequest_ == null) - hostcnnPingRequest_ = new SignonPingReq(12345); - - connectedServer.sendAndReceive(hostcnnPingRequest_); - // If no exception was thrown, then the ping succeeded. - - isAlive = true; - } - else - { - // It's a "common service", which will accept a Signon Ping Request. - if (signonPingRequest_ == null) - signonPingRequest_ = new SignonPingReq(); - - connectedServer.sendAndDiscardReply(signonPingRequest_); - // If no exception was thrown, then the ping succeeded. - - isAlive = true; - } - } + isAlive = doPingRequest(connectedServer, false); } catch (Exception e) { - if (Trace.traceOn_) - Trace.log(Trace.DIAGNOSTIC, e); + if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, e); isAlive = false; } @@ -3349,7 +3324,7 @@ public SignonInfo setState(AS400Impl impl, CredentialVault credVault) aafIndicator_ = parentImpl.aafIndicator_; proxySeed_ = parentImpl.proxySeed_; remoteSeed_ = parentImpl.remoteSeed_; - userHandle_ = parentImpl.userHandle_; + userHandle_ = UNINITIALIZED; serverSeed_ = parentImpl.serverSeed_; clientSeed_ = parentImpl.clientSeed_; hostcnn_serverSeed_ = parentImpl.hostcnn_serverSeed_; @@ -3770,7 +3745,7 @@ synchronized private void hostcnnConnect(boolean authenticate) throws AS400Secur // If already have a connection or this object is not secure, or // hostcnn connect was already tried and failed, simply return. if (!reconnecting) - if (hostcnnServer_ != null || useSSLConnection_ == null || (signonInfo_ != null && getVRM() < 0x00070600)) + if (hostcnnServer_ != null || useSSLConnection_ == null || (signonInfo_ != null && getVRM() <= 0x00070500)) return; if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Attempting to connect to as-hostcnn server."); @@ -3953,20 +3928,22 @@ private synchronized void signonConnect() throws AS400SecurityException, IOExcep if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Attempting to connect to as-signon server."); boolean connectedSuccessfully = false; - - SocketContainer signonConnection = PortMapper.getServerSocket((systemNameLocal_) ? "localhost" : systemName_, - AS400.SIGNON, useSSLConnection_, socketProperties_, mustUseNetSockets_); - AS400NoThreadServer signonServer = new AS400NoThreadServer(this, AS400.SIGNON, signonConnection, ""); - int connectionID = signonConnection.hashCode(); + AS400NoThreadServer signonServer = null; try { + SocketContainer signonConnection = PortMapper.getServerSocket((systemNameLocal_) ? "localhost" : systemName_, + AS400.SIGNON, useSSLConnection_, socketProperties_, mustUseNetSockets_); + + signonServer = new AS400NoThreadServer(this, AS400.SIGNON, signonConnection, ""); + + int connectionID = signonConnection.hashCode(); + InputStream inStream = signonConnection.getInputStream(); OutputStream outStream = signonConnection.getOutputStream(); clientSeed_ = (credVault_.getType() == AS400.AUTHENTICATION_SCHEME_PASSWORD) - ? BinaryConverter.longToByteArray(System.currentTimeMillis()) - : null; + ? BinaryConverter.longToByteArray(System.currentTimeMillis()) : null; SignonExchangeAttributeReq attrReq = new SignonExchangeAttributeReq(AS400Server.getServerId(AS400.SIGNON), clientSeed_); if (Trace.traceOn_) attrReq.setConnectionID(connectionID); @@ -4988,63 +4965,6 @@ public int getBidiStringType() { } // @Bidi-HCG3 end - //@ACAA Start - public int createUserHandle2() throws AS400SecurityException, IOException - { - if (UserHandle2_ != UNINITIALIZED) - return UserHandle2_; - - ClientAccessDataStream ds = null; - - AS400Server connectedServer = getConnectedServer(new int[] { AS400.FILE }); - if (connectedServer != null) - { - try - { - byte[] authenticationBytes = (gssCredential_ == null) - ? TokenManager.getGSSToken(systemName_, gssName_) - : TokenManager2.getGSSToken(systemName_, gssCredential_); - - IFSUserHandle2Req req = new IFSUserHandle2Req(authenticationBytes); - ds = (ClientAccessDataStream) connectedServer.sendAndReceive(req); - } catch (InterruptedException e) { - Trace.log(Trace.ERROR, "Interrupted"); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } catch (Throwable e) { - Trace.log(Trace.ERROR, "Error retrieving GSSToken:", e); - throw new AS400SecurityException(AS400SecurityException.KERBEROS_TICKET_NOT_VALID_RETRIEVE, e); - } - - int rc = 0; - // Verify the reply. - if (ds instanceof IFSCreateUserHandleRep) - { - rc = ((IFSCreateUserHandleRep) ds).getReturnCode(); - if (rc != IFSReturnCodeRep.SUCCESS) Trace.log(Trace.ERROR, "IFSCreateUserHandleRep return code", rc); - - UserHandle2_ = ((IFSCreateUserHandleRep) ds).getHandle(); - } - else if (ds instanceof IFSReturnCodeRep) - { - rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc != IFSReturnCodeRep.SUCCESS) Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); - - throw new ExtendedIOException(rc); - } - else - { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", ds.getReqRepID()); - throw new InternalErrorException(InternalErrorException.DATA_STREAM_UNKNOWN, Integer.toHexString(ds.getReqRepID()), null); - } - } - - setUserHandle(UserHandle2_); - return UserHandle2_; - } - //Generate salt for password level 4 /* * The following steps describe the algorithm used to generate the pwdlvl 4 version of the password: @@ -5170,8 +5090,7 @@ public void setVRM(int v, int r, int m) @Override public void setAdditionalAuthenticationFactor(char[] additionalAuthFactor) { - additionalAuthFactor_ = null; - if (null != additionalAuthFactor && 0 < additionalAuthFactor.length ) - additionalAuthFactor_ = Arrays.copyOf(additionalAuthFactor, additionalAuthFactor.length); + additionalAuthFactor_ = (null != additionalAuthFactor && 0 < additionalAuthFactor.length ) + ? (new String(additionalAuthFactor)).getBytes(StandardCharsets.UTF_8) : null; } } \ No newline at end of file diff --git a/src/main/java/com/ibm/as400/access/AS400StrSvrDS.java b/src/main/java/com/ibm/as400/access/AS400StrSvrDS.java index c77b0f61d..7bb34c5be 100644 --- a/src/main/java/com/ibm/as400/access/AS400StrSvrDS.java +++ b/src/main/java/com/ibm/as400/access/AS400StrSvrDS.java @@ -15,7 +15,6 @@ import java.io.IOException; import java.io.OutputStream; -import java.io.UnsupportedEncodingException; // A class representing a "start server" request data stream. class AS400StrSvrDS extends ClientAccessDataStream @@ -82,7 +81,7 @@ else if (authenticationBytes.length == 20) } - AS400StrSvrDS(int serverId, byte[] userIDbytes, byte[] authenticationBytes, int byteType, char[] addAuthFactor) + AS400StrSvrDS(int serverId, byte[] userIDbytes, byte[] authenticationBytes, int byteType, byte[] addAuthFactor) { super(new byte[((userIDbytes == null) ? 28 + authenticationBytes.length @@ -149,25 +148,15 @@ else if (authenticationBytes.length == 20) if (addAuthFactor != null && addAuthFactor.length > 0) { - byte[] aafBytes; - try { - aafBytes = new String(addAuthFactor).getBytes("UTF-8"); - } - catch (UnsupportedEncodingException e) { - // should never happen - Trace.log(Trace.ERROR, e); - throw new InternalErrorException(InternalErrorException.UNEXPECTED_EXCEPTION, e); - } - // Set additional authentication factor // LL - set32bit(4 + 2 + 4 + aafBytes.length, offset); + set32bit(4 + 2 + 4 + addAuthFactor.length, offset); // CP set16bit(0x112F, offset + 4); // CCSID set32bit(1208, offset + 6); // Data (Additional authentication factor in UTF-8) - System.arraycopy(aafBytes, 0, data_, offset + 10, aafBytes.length); + System.arraycopy(addAuthFactor, 0, data_, offset + 10, addAuthFactor.length); } } diff --git a/src/main/java/com/ibm/as400/access/ChangePasswordDialog.java b/src/main/java/com/ibm/as400/access/ChangePasswordDialog.java index 2e84303db..2793f8d9e 100644 --- a/src/main/java/com/ibm/as400/access/ChangePasswordDialog.java +++ b/src/main/java/com/ibm/as400/access/ChangePasswordDialog.java @@ -43,6 +43,7 @@ class ChangePasswordDialog extends Dialog private TextField oldTextField_; // Text field for current password. private TextField newTextField_; // Text field for new password. private TextField confirmTextField_; // Text field for password confirmation. + private TextField additionalFactorTextField_; // Text field for additional factor private Button okButton_; private Button cancelButton_; private Label passwordLabel_; @@ -52,6 +53,11 @@ class ChangePasswordDialog extends Dialog // @param parent The parent Window. // @param titleText The window title. ChangePasswordDialog(Frame parent, String titleText) + { + this(parent, titleText, false); + } + + ChangePasswordDialog(Frame parent, String titleText, boolean showshowAdditionalFactorFactor) { super(parent, titleText, true); @@ -67,64 +73,74 @@ class ChangePasswordDialog extends Dialog // Set the background color to light gray. setBackground(Color.lightGray); - // Create the 'System:' Label and add to the panel. + // Create the 'System:' Label and text field Label label = new Label(ResourceBundleLoader.getCoreText("DLG_SYSTEM_LABEL"), Label.LEFT); add(this, label, constraints, 0, 0, 1, 1); - // Create the system text field and add to the panel. systemNameTextField_ = new TextField(10); systemNameTextField_.setEnabled(false); add(this, systemNameTextField_, constraints, 1, 0, 1, 1); - // Create the 'User ID:' Label and add to the panel. + // Create the 'User ID:' Label and text field label = new Label(ResourceBundleLoader.getCoreText("DLG_USER_ID_LABEL"), Label.LEFT); add(this, label, constraints, 0, 1, 1, 1); - // Create the user id text field and add to the panel. userIdTextField_ = new TextField(10); userIdTextField_.setEnabled(false); add(this, userIdTextField_, constraints, 1, 1, 1, 1); + + // Create group label that will contain old and new passwords passwordLabel_ = new Label(ResourceBundleLoader.getText("DLG_PASSWORDS_LABEL"), Label.CENTER); add(this, passwordLabel_, constraints, 0,2,1,1); - // Create the old password label. + // Create the old password label and field label = new Label(ResourceBundleLoader.getText("DLG_OLD_LABEL"), Label.LEFT); add(this, label, constraints, 0, 3, 1, 1); - // Create the old password text field. oldTextField_ = new TextField(10); oldTextField_.setEchoChar('*'); oldTextField_.addFocusListener(listener_); oldTextField_.addKeyListener(listener_); add(this, oldTextField_, constraints, 1, 3, 1, 1); - // Create the new password label. + // Create the new password label and field label = new Label(ResourceBundleLoader.getText("DLG_NEW_LABEL"), Label.LEFT); add(this, label, constraints, 0, 4, 1, 1); - // Create the new password text field. newTextField_ = new TextField(10); newTextField_.setEchoChar('*'); newTextField_.addFocusListener(listener_); newTextField_.addKeyListener(listener_); add(this, newTextField_, constraints, 1, 4, 1, 1); - // Create the confirm password label. + // Create the confirm password label and field label = new Label(ResourceBundleLoader.getText("DLG_CONFIRM_LABEL"), Label.LEFT); add(this, label, constraints, 0, 5, 1, 1); - // Create the confirm password text field. confirmTextField_ = new TextField(10); confirmTextField_.setEchoChar('*'); confirmTextField_.addFocusListener(listener_); confirmTextField_.addKeyListener(listener_); add(this, confirmTextField_, constraints, 1, 5, 1, 1); + // Create the authentication factor label/field. + if (showshowAdditionalFactorFactor) + { + label = new Label(ResourceBundleLoader.getText("DLG_ADDITIONAL_FACTOR_LABEL"), Label.LEFT); + add(this, label, constraints, 0, 6, 1, 1); + + additionalFactorTextField_ = new TextField(10); + additionalFactorTextField_.addFocusListener(listener_); + additionalFactorTextField_.addKeyListener(listener_); + add(this, additionalFactorTextField_, constraints, 1, 6, 1, 1); + } + // Create panels to hold the 'OK', and 'Cancel' buttons. centeringPanel_ = new Panel(); centeringPanel_.setLayout(new FlowLayout(FlowLayout.CENTER)); constraints.insets = new Insets(8, 8, 8, 8); - add(this, centeringPanel_, constraints, 0, 6, 2, 1); + add(this, centeringPanel_, constraints, 0, showshowAdditionalFactorFactor ? 7 : 6, 2, 1); + Panel buttonPanel = new Panel(); buttonPanel.setLayout(new GridLayout(1, 2, 8, 0)); centeringPanel_.add(buttonPanel); @@ -135,6 +151,7 @@ class ChangePasswordDialog extends Dialog okButton_.addFocusListener(listener_); okButton_.addKeyListener(listener_); buttonPanel.add(okButton_); + cancelButton_ = new Button(ResourceBundleLoader.getCoreText("DLG_CANCEL_BUTTON")); cancelButton_.addActionListener(listener_); cancelButton_.addFocusListener(listener_); @@ -155,7 +172,9 @@ public void paint(Graphics gc) int left = pos.x/2; int top = pos.height/2 + pos.y; int right = (getBounds().width + confirmTextField_.getBounds().x + confirmTextField_.getBounds().width) / 2; - int bottom = (centeringPanel_.getBounds().y + confirmTextField_.getBounds().y + confirmTextField_.getBounds().height) / 2; + int bottom = (additionalFactorTextField_ == null) + ? (centeringPanel_.getBounds().y + confirmTextField_.getBounds().y + confirmTextField_.getBounds().height) / 2 + : (additionalFactorTextField_.getBounds().y + confirmTextField_.getBounds().y + confirmTextField_.getBounds().height) / 2; gc.setColor(Color.white); // Use white to make it look bevelled! gc.drawRect(left+1, top+1, right-left, bottom-top); @@ -175,6 +194,9 @@ boolean prompt(String systemName, String userId) // Set the system name and user ID text fields. systemNameTextField_.setText(systemName); userIdTextField_.setText(userId); + + if (additionalFactorTextField_ != null) + additionalFactorTextField_.setText(""); // Clear the password text fields. oldTextField_.setText(""); @@ -211,6 +233,13 @@ String getConfirmPassword() return confirmTextField_.getText(); } + // This method returns the additional factor. + // @return The factor. + String getAdditionalFactor() + { + return (additionalFactorTextField_ != null) ? additionalFactorTextField_.getText() : ""; + } + // This methods adds a user interface component to the specified container using the specified constraints. // @param container The container to add the component to. // @param component The user interface component to add. diff --git a/src/main/java/com/ibm/as400/access/ChangePasswordReq.java b/src/main/java/com/ibm/as400/access/ChangePasswordReq.java index f5b7f2047..f22fada7b 100644 --- a/src/main/java/com/ibm/as400/access/ChangePasswordReq.java +++ b/src/main/java/com/ibm/as400/access/ChangePasswordReq.java @@ -15,15 +15,17 @@ import java.io.IOException; import java.io.OutputStream; -import java.io.UnsupportedEncodingException; class ChangePasswordReq extends ClientAccessDataStream { ChangePasswordReq(byte[] userID, byte[] encryptedPw, byte[] oldPassword, int oldPasswordLength, - byte[] newPassword, int newPasswordLength, int serverLevel, char[] addAuthFactor) + byte[] newPassword, int newPasswordLength, int serverLevel, byte[] addAuthFactor) { - super(new byte[(encryptedPw.length == 64 ? 107 : 63) + oldPassword.length + newPassword.length - + (encryptedPw.length == 8 ? 0 : 42) + (serverLevel < 5 ? 0 : 7) + (serverLevel >= 18 && null != addAuthFactor && 0 < addAuthFactor.length ? 10 + addAuthFactor.length :0)]); + super(new byte[(encryptedPw.length == 64 ? 107 : 63) + + oldPassword.length + newPassword.length + + (encryptedPw.length == 8 ? 0 : 42) + + (serverLevel < 5 ? 0 : 7) + + (serverLevel >= 18 && null != addAuthFactor && 0 < addAuthFactor.length ? 10 + addAuthFactor.length :0)]); setLength(data_.length); // setHeaderID(0x0000); @@ -127,30 +129,21 @@ class ChangePasswordReq extends ClientAccessDataStream if (serverLevel >= 18 && null != addAuthFactor && 0 < addAuthFactor.length) { - byte[] aafBytes; - try { - aafBytes = new String(addAuthFactor).getBytes("UTF-8"); - } - catch (UnsupportedEncodingException e) { - // should never happen - Trace.log(Trace.ERROR, e); - throw new InternalErrorException(InternalErrorException.UNEXPECTED_EXCEPTION, e); - } - // LL - set32bit(aafBytes.length + 4 + 2 + 4, offset); + set32bit(addAuthFactor.length + 4 + 2 + 4, offset); // CP set16bit(0x112F, offset + 4); // CCSID set32bit(1208, offset + 6); // data - System.arraycopy(aafBytes, 0, data_, offset + 10, aafBytes.length); + System.arraycopy(addAuthFactor, 0, data_, offset + 10, addAuthFactor.length); - offset += 10 + aafBytes.length; + offset += 10 + addAuthFactor.length; } } } + @Override void write(OutputStream out) throws IOException { if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Sending change password request..."); diff --git a/src/main/java/com/ibm/as400/access/ClassDecoupler.java b/src/main/java/com/ibm/as400/access/ClassDecoupler.java index 602bb35af..42d55ca25 100644 --- a/src/main/java/com/ibm/as400/access/ClassDecoupler.java +++ b/src/main/java/com/ibm/as400/access/ClassDecoupler.java @@ -17,7 +17,6 @@ import java.security.GeneralSecurityException; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; -import java.security.NoSuchAlgorithmException; import java.util.*; /** @@ -37,8 +36,9 @@ public class ClassDecoupler // AS400Server.addReplyStream(new DDMASPReplyDataStream(), AS400.RECORDACCESS); // } - /* @U4A force the use of ENCUSRPWD or AES using JVM properties */ + /** force the use of ENCUSRPWD using JVM properties */ public static boolean forceENCUSRPWD = false; + /** force the use of AES using JVM properties */ public static boolean forceAES = false; static { @@ -232,16 +232,16 @@ else if ((authScheme == AS400.AUTHENTICATION_SCHEME_PASSWORD) || (authSchemeToUs return new Object[] { clientSeed, serverSeed, jobString, encryptUserId, keyPair }; } - /*@U4C*/ static void connectDDMPhase2(OutputStream outStream, InputStream inStream, byte[] userIDbytes, byte[] ddmSubstitutePassword, byte[] iaspBytes, int authScheme, String ddmRDB, - String systemName, int connectionID) throws ServerStartupException, IOException, AS400SecurityException + String systemName, int connectionID, + byte[] addAuthFactor) throws ServerStartupException, IOException, AS400SecurityException { // If the ddmSubstitutePassword length is 8, then we are using DES encryption. // If its length is 20, then we are using SHA encryption. // Build the SECCHK request; we build the request here so that we are not // passing the password around anymore than we have to. - DDMSECCHKRequestDataStream SECCHKReq = new DDMSECCHKRequestDataStream(userIDbytes, ddmSubstitutePassword, iaspBytes, authScheme); + DDMSECCHKRequestDataStream SECCHKReq = new DDMSECCHKRequestDataStream(userIDbytes, ddmSubstitutePassword, iaspBytes, authScheme, addAuthFactor); if (Trace.traceOn_) SECCHKReq.setConnectionID(connectionID); // Send the SECCHK request. diff --git a/src/main/java/com/ibm/as400/access/CoreMRI.java b/src/main/java/com/ibm/as400/access/CoreMRI.java index adcbfa6d8..ddd273131 100644 --- a/src/main/java/com/ibm/as400/access/CoreMRI.java +++ b/src/main/java/com/ibm/as400/access/CoreMRI.java @@ -55,6 +55,7 @@ public Object[][] getContents() { "DLG_PASSWORD_LABEL", "Password:" }, { "DLG_SYSTEM_LABEL", "System:" }, { "DLG_USER_ID_LABEL", "User ID:" }, + { "DLG_ADDITIONAL_FACTOR_LABEL", "Additional factor:" }, { "DLG_CANCEL_BUTTON", "Cancel" }, { "DLG_OK_BUTTON", "OK" }, { "DLG_CACHE_PASSWORD_CHECK_BOX", "Save password" }, diff --git a/src/main/java/com/ibm/as400/access/DDMSECCHKRequestDataStream.java b/src/main/java/com/ibm/as400/access/DDMSECCHKRequestDataStream.java index 0abc0ee52..faf0baa63 100644 --- a/src/main/java/com/ibm/as400/access/DDMSECCHKRequestDataStream.java +++ b/src/main/java/com/ibm/as400/access/DDMSECCHKRequestDataStream.java @@ -21,15 +21,18 @@ //Term = SECCHK. class DDMSECCHKRequestDataStream extends DDMDataStream { - private static final String copyright = "Copyright (C) 1997-2003 International Business Machines Corporation and others."; + private static final String copyright = "Copyright (C) 1997-2024 International Business Machines Corporation and others."; - DDMSECCHKRequestDataStream(byte[] userIDbytes, byte[] authenticationBytes, byte[] iasp, int authScheme) + DDMSECCHKRequestDataStream(byte[] userIDbytes, byte[] authenticationBytes, byte[] iasp, int authScheme, + byte[] addAuthFactor) { super(new byte[authenticationBytes.length + userIDbytes.length + - (iasp == null ? 0 : 22) + - ((authScheme == AS400.AUTHENTICATION_SCHEME_PASSWORD) || - (authScheme == AS400.AUTHENTICATION_SCHEME_DDM_EUSERIDPWD) ? 24 : 16)]); - + (iasp == null ? 0 : 22) + + ((authScheme == AS400.AUTHENTICATION_SCHEME_PASSWORD + || authScheme == AS400.AUTHENTICATION_SCHEME_DDM_EUSERIDPWD) ? 24 : 16) + + (((authScheme == AS400.AUTHENTICATION_SCHEME_PASSWORD + || authScheme == AS400.AUTHENTICATION_SCHEME_DDM_EUSERIDPWD) && addAuthFactor != null) ? addAuthFactor.length + 12: 0)]); + // Initialize the header: Don't continue on error, not chained, GDS id = D0, // type = RQSDSS, no same request correlation. setGDSId((byte) 0xD0); @@ -61,17 +64,16 @@ class DDMSECCHKRequestDataStream extends DDMDataStream System.arraycopy(authenticationBytes, 0, data_, 26, authenticationBytes.length); int offset = 26 + authenticationBytes.length; - } + } else - { - + { boolean useRDB = (iasp != null); // setIsChained(false); // setContinueOnError(false); // setHasSameRequestCorrelation(false); setType(1); // 1 = RQSDSS - set16bit(authenticationBytes.length + userIDbytes.length+ (useRDB ? 40 : 18), 6); // Set LL SECCHK term. + set16bit(authenticationBytes.length + userIDbytes.length + (useRDB ? 40 : 18) + ((addAuthFactor != null && 0 < addAuthFactor.length) ? addAuthFactor.length + 12 : 0), 6); // Set LL for SECCHK term. set16bit(DDMTerm.SECCHK, 8); // Set code point for SECCHK. set16bit(6, 10); // Set LL for SECMEC term. set16bit(DDMTerm.SECMEC, 12); // Set code point for SECMEC. @@ -115,6 +117,20 @@ else if (authenticationBytes.length == 20 || authenticationBytes.length == 64) offset += 22; } + + if (addAuthFactor != null) + { + if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Sending SECCHK request with additional authentication factor."); + + set16bit(12 + addAuthFactor.length, offset); // LL + set16bit(DDMTerm.SXXFACTOR, offset + 2); // Term/Code point + set16bit(0, offset + 4); // version + set32bit(1208, offset + 6); // ccsid + set16bit(addAuthFactor.length, offset + 10); // LL for data item + System.arraycopy(addAuthFactor, 0, data_, offset + 12, addAuthFactor.length); // Data + + offset += 12 + addAuthFactor.length; + } } } diff --git a/src/main/java/com/ibm/as400/access/IFSCreateUserHandlerReq.java b/src/main/java/com/ibm/as400/access/IFSCreateUserHandlerReq.java index 8d8142277..5f585c235 100644 --- a/src/main/java/com/ibm/as400/access/IFSCreateUserHandlerReq.java +++ b/src/main/java/com/ibm/as400/access/IFSCreateUserHandlerReq.java @@ -12,25 +12,45 @@ /////////////////////////////////////////////////////////////////////////////// package com.ibm.as400.access; -public class IFSCreateUserHandlerReq extends IFSDataStreamReq { +public class IFSCreateUserHandlerReq extends IFSDataStreamReq +{ + private static final int TEMPLATE_LENGTH = 12; - private static final int TEMPLATE_LENGTH = 12; - private static final int USER_ID_OFFSET = 22; - private static final int PASSWORD_OFFSET = 32; - - protected IFSCreateUserHandlerReq(byte[] userID, byte[] password) { - super(HEADER_LENGTH + TEMPLATE_LENGTH + password.length); - setLength(data_.length); - setTemplateLen(TEMPLATE_LENGTH + password.length); - setReqRepID(0x0024); + protected IFSCreateUserHandlerReq(byte[] userID, byte[] password) { + this(userID, password, null); + } - set32bit(userID.length, USER_ID_OFFSET); - System.arraycopy(userID, 0, data_, USER_ID_OFFSET, userID.length); - - set64bit(password.length, PASSWORD_OFFSET); - System.arraycopy(password, 0, data_, PASSWORD_OFFSET, password.length); - } + protected IFSCreateUserHandlerReq(byte[] userID, byte[] password, byte[] addAuthFactor) + { + super(HEADER_LENGTH + TEMPLATE_LENGTH + password.length + + (null != addAuthFactor && 0 < addAuthFactor.length ? 10 + addAuthFactor.length :0)); + setLength(data_.length); + setTemplateLen(TEMPLATE_LENGTH + password.length); + setReqRepID(0x0024); + + int offset = 22; + + // Data - user ID + System.arraycopy(userID, 0, data_, offset, userID.length); + offset += 10; - - + // Data - substituted password + System.arraycopy(password, 0, data_, offset, password.length); + offset += password.length; + + // Authentication factor + if (addAuthFactor != null && addAuthFactor.length > 0) + { + //LL + set32bit(addAuthFactor.length + 4 + 2 + 4, offset); + // CP + set16bit(0x0015, offset + 4); + // CCSID + set32bit(1208, offset + 6); + // data + System.arraycopy(addAuthFactor, 0, data_, offset + 10, addAuthFactor.length); + + offset += 10 + addAuthFactor.length; + } + } } diff --git a/src/main/java/com/ibm/as400/access/IFSFile.java b/src/main/java/com/ibm/as400/access/IFSFile.java index ab84984db..f1ecda988 100644 --- a/src/main/java/com/ibm/as400/access/IFSFile.java +++ b/src/main/java/com/ibm/as400/access/IFSFile.java @@ -1267,30 +1267,27 @@ else if (pathElem.equals(DOTDOT)) @return The file's CCSID. @exception IOException If an error occurs while communicating with the system. **/ - public int getCCSID() - throws IOException - { - int result = -1; - try - { - if (impl_ == null) - chooseImpl(); + public int getCCSID() throws IOException + { + try + { + if (impl_ == null) + chooseImpl(); - //@SCa - if(this.isDirectory() && getSystem().getAuthenticationScheme()== AS400.AUTHENTICATION_SCHEME_PASSWORD){ //@T2C - result = impl_.getCCSIDByUserHandle();//@V4C - }else + // In 7.5 and prior releases, need to create user handle for IFS tables to be initialized. + // Not sure why only for directories. + if (this.isDirectory() + && (getSystem().getAuthenticationScheme()== AS400.AUTHENTICATION_SCHEME_PASSWORD + || getSystem().getAuthenticationScheme()== AS400.AUTHENTICATION_SCHEME_GSS_TOKEN)) + return impl_.getCCSIDByUserHandle(); + + return impl_.getCCSID(true); + } + catch (AS400SecurityException e) { - //result = impl_.getCCSID(); - result = impl_.getCCSID(true); //@AC7 + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); } - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); - } - return result; } @@ -1510,33 +1507,26 @@ public String getName() @exception IOException If an error occurs while communicating with the system. @exception ExtendedIOException If the file does not exist. **/ - public String getOwnerName() - throws IOException, - AS400SecurityException + public String getOwnerName() throws IOException, AS400SecurityException { - // Design note: The File Server doesn't support changing the owner name. - // It only supports retrieving it. Hence we do not provide a setOwnerName() method. + // Design note: The File Server doesn't support changing the owner name. + // It only supports retrieving it. Hence we do not provide a setOwnerName() method. - if (impl_ == null) - chooseImpl(); + if (impl_ == null) + chooseImpl(); - //@SCa - if(this.isDirectory() && getSystem().getAuthenticationScheme()== AS400.AUTHENTICATION_SCHEME_PASSWORD){//@T2C - //return impl_.getOwnerNameByUserHandle();//@V4C - return impl_.getOwnerNameByUserHandle(false); //@AC7 - } - else - //return impl_.getOwnerName(); //@AE8D - //@AE8A - { - String pathUpperCase = path_.toUpperCase(system_.getLocale()); - if (pathUpperCase.startsWith("/QSYS.LIB") && !pathUpperCase.endsWith(".FILE")) { - return impl_.getOwnerNameByUserHandle(); - } else { - return impl_.getOwnerName(true); //@AC7 - } - } - + // In 7.5 and prior releases, need to create user handle for IFS tables to be initialized. + // Not sure why only for directories. + if (this.isDirectory() + && (getSystem().getAuthenticationScheme()== AS400.AUTHENTICATION_SCHEME_PASSWORD + || getSystem().getAuthenticationScheme()== AS400.AUTHENTICATION_SCHEME_GSS_TOKEN)) + return impl_.getOwnerNameByUserHandle(false); + + String pathUpperCase = path_.toUpperCase(system_.getLocale()); + if (pathUpperCase.startsWith("/QSYS.LIB") && !pathUpperCase.endsWith(".FILE")) + return impl_.getOwnerNameByUserHandle(); + + return impl_.getOwnerName(true); } @@ -1838,9 +1828,9 @@ For further information, refer to the specification of the QDBRTVFD (Retrieve Da public boolean isSourcePhysicalFile() throws AS400Exception, AS400SecurityException, IOException { - String pathUpperCase = path_.toUpperCase(system_.getLocale()); //@AE8A + String pathUpperCase = path_.toUpperCase(system_.getLocale()); //@AE8A if (!pathUpperCase.endsWith(".FILE") || - pathUpperCase.indexOf("/QSYS.LIB") == -1 || + pathUpperCase.indexOf("/QSYS.LIB") == -1 || !getSubtype().equals("PF")) { if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Not a physical file."); @@ -1873,22 +1863,19 @@ public AS400 getSystem() @throws IOException If an error occurs while communicating with the system. @throws AS400SecurityException If a security or authority error occurs. **/ -//@AC7 Start + public int getASP(boolean retrieveAll) throws IOException, AS400SecurityException { - if (impl_ == null) - chooseImpl(); - if(getSystem().getAuthenticationScheme()== AS400.AUTHENTICATION_SCHEME_PASSWORD){ - if (retrieveAll) - return impl_.getASP(this.isDirectory()); - else - return impl_.getASP(); - } - return -1; + if (impl_ == null) + chooseImpl(); + + if (getSystem().getAuthenticationScheme() == AS400.AUTHENTICATION_SCHEME_PASSWORD + || getSystem().getAuthenticationScheme()== AS400.AUTHENTICATION_SCHEME_GSS_TOKEN) + return (retrieveAll) ? impl_.getASP(this.isDirectory()) : impl_.getASP(); + + return -1; } -//@AC7 End - //@RDA /**Return the auxiliary storage pool (ASP) that holds the object. Note only password authentication scheme is supported, otherwise returns -1. @return Return the auxiliary storage pool (ASP) that holds the object. Possible values are: @@ -1901,17 +1888,16 @@ public int getASP(boolean retrieveAll) throws IOException, AS400SecurityExceptio @throws IOException If an error occurs while communicating with the system. @throws AS400SecurityException If a security or authority error occurs. **/ - public int getASP()//@SAC - throws IOException, - AS400SecurityException + public int getASP() throws IOException, AS400SecurityException { - - if (impl_ == null) - chooseImpl(); - if(getSystem().getAuthenticationScheme()== AS400.AUTHENTICATION_SCHEME_PASSWORD){//@T2A - return impl_.getASP();//@V4C - } - return -1;//@T2A + if (impl_ == null) + chooseImpl(); + + if (getSystem().getAuthenticationScheme() == AS400.AUTHENTICATION_SCHEME_PASSWORD + || getSystem().getAuthenticationScheme()== AS400.AUTHENTICATION_SCHEME_GSS_TOKEN) + impl_.getASP(); + + return -1; } //@AC7 Start @@ -1922,51 +1908,47 @@ public int getASP()//@SAC @throws IOException If an error occurs while communicating with the system. @throws AS400SecurityException If a security or authority error occurs. **/ - public String getFileSystemType(boolean retrieveAll) throws IOException, AS400SecurityException { - if (cachedAttributes_ != null) { - int fileSystemType = cachedAttributes_.getFileSystemType(); - if (fileSystemType == 2) - return "QDLS"; - else if (fileSystemType == 3) - return "QSYS"; - } - if (impl_ == null) - chooseImpl(); - if(getSystem().getAuthenticationScheme()== AS400.AUTHENTICATION_SCHEME_PASSWORD){ - if (retrieveAll) - return impl_.getFileSystemType(this.isDirectory()); - else - return impl_.getFileSystemType(); - } - return ""; - } -//@AC7 End + public String getFileSystemType(boolean retrieveAll) throws IOException, AS400SecurityException + { + if (cachedAttributes_ != null) + { + int fileSystemType = cachedAttributes_.getFileSystemType(); + if (fileSystemType == 2) + return "QDLS"; + else if (fileSystemType == 3) + return "QSYS"; + } + + if (impl_ == null) + chooseImpl(); + + if (getSystem().getAuthenticationScheme() == AS400.AUTHENTICATION_SCHEME_PASSWORD) + return (retrieveAll) ? impl_.getFileSystemType(this.isDirectory()) : impl_.getFileSystemType(); + + return ""; + } - //@SAA /**Return the type of file system. Note only password authentication scheme is supported, otherwise returns "". @return Return the type of file system. Possible values are:EPFS,QDLS,QSYS,NFS,LRFS,QOPT,QRFS,EPFSP,QNETC,QDTL,IEPFS,ASPQSYS @throws IOException If an error occurs while communicating with the system. @throws AS400SecurityException If a security or authority error occurs. **/ - public String getFileSystemType() throws IOException, AS400SecurityException { - //@AC7 Start - if (cachedAttributes_ != null) { - int fileSystemType = cachedAttributes_.getFileSystemType(); - if (fileSystemType == 2) - return "QDLS"; - else if (fileSystemType == 3) - return "QSYS"; - } - //@AC7 End - - if (impl_ == null) - chooseImpl(); + public String getFileSystemType() throws IOException, AS400SecurityException + { + if (cachedAttributes_ != null) + { + int fileSystemType = cachedAttributes_.getFileSystemType(); + if (fileSystemType == 2) + return "QDLS"; + else if (fileSystemType == 3) + return "QSYS"; + } + + if (impl_ == null) + chooseImpl(); - if(getSystem().getAuthenticationScheme()== AS400.AUTHENTICATION_SCHEME_PASSWORD){//@T2A - return impl_.getFileSystemType();//@V4C - } - return "";//@T2A + return (getSystem().getAuthenticationScheme() == AS400.AUTHENTICATION_SCHEME_PASSWORD) ? impl_.getFileSystemType() : ""; } /** @@ -2027,29 +2009,29 @@ public boolean isAbsolute() //internal isDirectory that returns a return code status indicator int isDirectory0() throws IOException, AS400SecurityException { - //@A7A Added check for cached attributes. - if (cachedAttributes_ != null) { - if (isDirectory_) { - return IFSReturnCodeRep.SUCCESS; - } else - return IFSReturnCodeRep.FILE_NOT_FOUND; - } else { - //@AC7 Start - if (isDirectoryInited_) { - if (isDirectory_) { - return IFSReturnCodeRep.SUCCESS; - } else - return IFSReturnCodeRep.FILE_NOT_FOUND; - } else { - if (impl_ == null) - chooseImpl(); - int rc = impl_.isDirectory(); - isDirectory_ = rc == 0? true : false; - isDirectoryInited_ = true; - return rc; - } - } - } + //@A7A Added check for cached attributes. + if (cachedAttributes_ != null) { + if (isDirectory_) { + return IFSReturnCodeRep.SUCCESS; + } else + return IFSReturnCodeRep.FILE_NOT_FOUND; + } else { + //@AC7 Start + if (isDirectoryInited_) { + if (isDirectory_) { + return IFSReturnCodeRep.SUCCESS; + } else + return IFSReturnCodeRep.FILE_NOT_FOUND; + } else { + if (impl_ == null) + chooseImpl(); + int rc = impl_.isDirectory(); + isDirectory_ = rc == 0? true : false; + isDirectoryInited_ = true; + return rc; + } + } + } //@AC7 End /** diff --git a/src/main/java/com/ibm/as400/access/IFSFileDescriptorImplRemote.java b/src/main/java/com/ibm/as400/access/IFSFileDescriptorImplRemote.java index f775fe4a8..e56797de0 100644 --- a/src/main/java/com/ibm/as400/access/IFSFileDescriptorImplRemote.java +++ b/src/main/java/com/ibm/as400/access/IFSFileDescriptorImplRemote.java @@ -638,64 +638,64 @@ ConverterImplRemote getConverter() //@AC7 Start public String getOwnerName() throws IOException { - if(fileOwnerName_ == null) { - try { - connect(); - IFSListAttrsRep reply = listObjAttrs12(IFSObjAttrs1.OWNER_NAME_FLAG, 0); - if (reply != null) { - fileOwnerName_ = reply.getOwnerName(system_.getCcsid()); - if (fileDataCCSID_ == UNINITIALIZED) { - fileDataCCSID_ = reply.getCCSID(serverDatastreamLevel_); - } - } else { - if (Trace.traceOn_) Trace.log(Trace.WARNING, "getOwnerName: IFSReturnCodeRep return code", errorRC_); - if (errorRC_ == IFSReturnCodeRep.FILE_NOT_FOUND || errorRC_ == IFSReturnCodeRep.PATH_NOT_FOUND) - { - throw new ExtendedIOException(path_, ExtendedIOException.PATH_NOT_FOUND); - } - } - } catch (ExtendedIOException e) { - if (e.getReturnCode() == ExtendedIOException.DIR_ENTRY_EXISTS) { - if (Trace.traceOn_) - Trace.log(Trace.WARNING, "Unable to determine owner of directory.", e); - } - else - throw e; - } catch (AS400SecurityException e) { - // The connect() method has already traced the error. - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); - } - } - return (fileOwnerName_ == null ? "" : fileOwnerName_); + if(fileOwnerName_ == null) { + try { + connect(); + IFSListAttrsRep reply = listObjAttrs12(IFSObjAttrs1.OWNER_NAME_FLAG, 0); + if (reply != null) { + fileOwnerName_ = reply.getOwnerName(system_.getCcsid()); + if (fileDataCCSID_ == UNINITIALIZED) { + fileDataCCSID_ = reply.getCCSID(serverDatastreamLevel_); + } + } else { + if (Trace.traceOn_) Trace.log(Trace.WARNING, "getOwnerName: IFSReturnCodeRep return code", errorRC_); + if (errorRC_ == IFSReturnCodeRep.FILE_NOT_FOUND || errorRC_ == IFSReturnCodeRep.PATH_NOT_FOUND) + { + throw new ExtendedIOException(path_, ExtendedIOException.PATH_NOT_FOUND); + } + } + } catch (ExtendedIOException e) { + if (e.getReturnCode() == ExtendedIOException.DIR_ENTRY_EXISTS) { + if (Trace.traceOn_) + Trace.log(Trace.WARNING, "Unable to determine owner of directory.", e); + } + else + throw e; + } catch (AS400SecurityException e) { + // The connect() method has already traced the error. + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } + } + return (fileOwnerName_ == null ? "" : fileOwnerName_); } public int getCCSID(boolean retrieveAll) throws IOException - { - if (fileDataCCSID_ == UNINITIALIZED) - { - try - { - // Ensure that we are connected to the server. - connect(); - - IFSListAttrsRep reply = null; - if (retrieveAll) - reply = listObjAttrs12(IFSObjAttrs1.OWNER_NAME_FLAG, 0); - else - reply = listObjAttrs2(); // the 'ccsid' field is in the OA2 structure - if (reply != null) { - fileDataCCSID_ = reply.getCCSID(serverDatastreamLevel_); - if (retrieveAll && fileOwnerName_ == null) - fileOwnerName_ = reply.getOwnerName(system_.getCcsid()); - } - } - catch (AS400SecurityException e) { - // The connect() method has already traced the error. - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); - } - } - return fileDataCCSID_; - } + { + if (fileDataCCSID_ == UNINITIALIZED) + { + try + { + // Ensure that we are connected to the server. + connect(); + + IFSListAttrsRep reply = null; + if (retrieveAll) + reply = listObjAttrs12(IFSObjAttrs1.OWNER_NAME_FLAG, 0); + else + reply = listObjAttrs2(); // the 'ccsid' field is in the OA2 structure + if (reply != null) { + fileDataCCSID_ = reply.getCCSID(serverDatastreamLevel_); + if (retrieveAll && fileOwnerName_ == null) + fileOwnerName_ = reply.getOwnerName(system_.getCcsid()); + } + } + catch (AS400SecurityException e) { + // The connect() method has already traced the error. + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } + } + return fileDataCCSID_; + } //@AC7 End @@ -726,74 +726,71 @@ public int getCCSID() } //@SCa @V4C User handle need to be free every time after the attr has been retrieve. Otherwise there may cause other problems. See cps ARUTDV - public int getCCSIDByUserHandle() throws IOException, AS400SecurityException{ - isDirectory_ = true; //@AC7A - if (fileDataCCSID_ == UNINITIALIZED) - { - ClientAccessDataStream ds = null; + public int getCCSIDByUserHandle() throws IOException, AS400SecurityException + { + isDirectory_ = true; + + if (fileDataCCSID_ == UNINITIALIZED) + { + ClientAccessDataStream ds = null; - connect(); + connect(); - //create user handle - int userHandle = UNINITIALIZED, objectHandle = UNINITIALIZED; - try{ - userHandle = system_.createUserHandle(); + //create user handle + int userHandle = UNINITIALIZED, objectHandle = UNINITIALIZED; + try + { + // In 7.5 and prior releases, need to create user handle for IFS tables to be initialized. + userHandle = (getSystem().getVRM() <= 0x00070500) ? system_.createUserHandle() : 0; - try - { - byte[] path = getConverter().stringToByteArray(path_); + try + { + byte[] path = getConverter().stringToByteArray(path_); - //IFSLookupReq req = new IFSLookupReq(path, preferredServerCCSID_, userHandle, IFSLookupReq.OA2, 0, 0); - IFSLookupReq req = new IFSLookupReq(path, preferredServerCCSID_, userHandle, IFSLookupReq.OA12, IFSObjAttrs1.OWNERANAME_ASP_FLAS, 0); //@AC7A - ds = (ClientAccessDataStream) server_.sendAndReceive(req); - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream server connection lost."); - connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted"); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } + IFSLookupReq req = new IFSLookupReq(path, preferredServerCCSID_, userHandle, IFSLookupReq.OA12, IFSObjAttrs1.OWNERANAME_ASP_FLAS, 0); //@AC7A + ds = (ClientAccessDataStream) server_.sendAndReceive(req); + } + catch(ConnectionDroppedException e) + { + Trace.log(Trace.ERROR, "Byte stream server connection lost."); + connectionDropped(e); + } + catch(InterruptedException e) + { + Trace.log(Trace.ERROR, "Interrupted"); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; + } - int rc = 0; - if (ds instanceof IFSLookupRep) - { - //fileDataCCSID_ = ((IFSLookupRep) ds).getCCSID(serverDatastreamLevel_); //@AC7D - objectHandle = ((IFSLookupRep) ds).getHandle(); - retrieveAttributes(ds, objectHandle); //@AC7A - } - else if (ds instanceof IFSReturnCodeRep) - { - rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc != IFSReturnCodeRep.SUCCESS) + int rc = 0; + if (ds instanceof IFSLookupRep) + { + objectHandle = ((IFSLookupRep) ds).getHandle(); + retrieveAttributes(ds, objectHandle); //@AC7A + } + else if (ds instanceof IFSReturnCodeRep) + { + rc = ((IFSReturnCodeRep) ds).getReturnCode(); + if (rc != IFSReturnCodeRep.SUCCESS) Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); + + throw new ExtendedIOException(path_, rc); + } + else + { + // Unknown data stream. + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.getReqRepID()); + throw new InternalErrorException(Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); + } + } + finally { - Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); + if (objectHandle != UNINITIALIZED) + freeHandle(objectHandle); } - throw new ExtendedIOException(path_, rc); - } - else - { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", - ds.getReqRepID()); - throw new - InternalErrorException(Integer.toHexString(ds.getReqRepID()), - InternalErrorException.DATA_STREAM_UNKNOWN); - } - }finally{ - // if(userHandle != UNINITIALIZED) - // freeUserHandle(userHandle); - if(objectHandle != UNINITIALIZED) - freeHandle(objectHandle); } - } - return fileDataCCSID_; + return fileDataCCSID_; } int getFileHandle() @@ -1013,7 +1010,7 @@ IFSListAttrsRep listObjAttrs2() //@AC7A Start IFSListAttrsRep listObjAttrs12(int flags1, int flags2) throws IOException, AS400SecurityException { - return listObjAttrs(IFSListAttrsReq.OA12, flags1, flags2); + return listObjAttrs(IFSListAttrsReq.OA12, flags1, flags2); } //@AC7A End @@ -1671,389 +1668,237 @@ public int getServerDatastreamLevel() { return serverDatastreamLevel_; } - //@V4A - public int createUserHandle() throws IOException, AS400SecurityException{ - ClientAccessDataStream ds = null; - int UserHandle = UNINITIALIZED; - int rc; - byte[] ClientSeed = BinaryConverter.longToByteArray(System.currentTimeMillis()); - byte[] ServerSeed = null; - try { - IFSUserHandleSeedReq req = new IFSUserHandleSeedReq(ClientSeed); - ds = (ClientAccessDataStream) server_.sendAndReceive(req); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted"); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } - // Verify that we got a handle back. - if (ds instanceof IFSUserHandleSeedRep) - { - ServerSeed = ((IFSUserHandleSeedRep) ds).getSeed(); - } - else if (ds instanceof IFSReturnCodeRep) - { - rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc != IFSReturnCodeRep.SUCCESS) - { - Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); - } - throw new ExtendedIOException(rc); - } - else - { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", - ds.getReqRepID()); - throw new - InternalErrorException(Integer.toHexString(ds.getReqRepID()), - InternalErrorException.DATA_STREAM_UNKNOWN); - } - - - rc = 0; - ds = null; - byte[] userIDbytes = SignonConverter.stringToByteArray(system_.getUserId()); - byte[] encryptedPassword = system_.getPassword(ClientSeed, ServerSeed); - IFSCreateUserHandlerReq req = new IFSCreateUserHandlerReq(userIDbytes, encryptedPassword); - try { - ds = (ClientAccessDataStream) server_.sendAndReceive(req); - } catch (InterruptedException e) { - Trace.log(Trace.ERROR, "Interrupted"); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } - - // Verify the reply. - if (ds instanceof IFSCreateUserHandleRep) - { - rc = ((IFSCreateUserHandleRep)ds).getReturnCode(); - if (rc != IFSReturnCodeRep.SUCCESS) - { - Trace.log(Trace.ERROR, "IFSCreateUserHandleRep return code", rc); - } - UserHandle = ((IFSCreateUserHandleRep) ds).getHandle(); - - } - else if (ds instanceof IFSReturnCodeRep) - { - rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc != IFSReturnCodeRep.SUCCESS) - { - Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); - } - throw new ExtendedIOException(rc); - } - else - { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", - ds.getReqRepID()); - throw new - InternalErrorException(InternalErrorException.DATA_STREAM_UNKNOWN, - Integer.toHexString(ds.getReqRepID()),null); - } - return UserHandle; - - } - - public void freeUserHandle(int userHandle) throws IOException, AS400SecurityException{ - IFSFreeUserHandlerReq req = new IFSFreeUserHandlerReq(userHandle); - server_.send(req); - } - public void freeHandle(int objectHandle) throws IOException, AS400SecurityException{ IFSFreeHandleReq req = new IFSFreeHandleReq(objectHandle); server_.send(req); } - //@AC7A Start public int getASP(boolean isDirectory) throws IOException, AS400SecurityException { - isDirectory_ = isDirectory; - return getASP(); + isDirectory_ = isDirectory; + return getASP(); } - //@AC7A End - public int getASP() throws IOException, AS400SecurityException { - if (fileAsp_ == UNINITIALIZED) - { - ClientAccessDataStream ds = null; - int rc = 0; + public int getASP() throws IOException, AS400SecurityException + { + if (fileAsp_ == UNINITIALIZED) + { + ClientAccessDataStream ds = null; + int rc = 0; - connect(); + connect(); - // Ensure that we are connected to the server. - byte[] pathname = getConverter().stringToByteArray(path_); + // Ensure that we are connected to the server. + byte[] pathname = getConverter().stringToByteArray(path_); - //create user handle - int userHandle = UNINITIALIZED, objectHandle = UNINITIALIZED; - try{ - userHandle = system_.createUserHandle(); - try - { - // Issue a Look up request to create an object handle. - //IFSLookupReq req = new IFSLookupReq(pathname, preferredServerCCSID_, userHandle, IFSLookupReq.OA1, IFSLookupReq.ASP_FLAG, 0); - IFSLookupReq req = new IFSLookupReq(pathname, preferredServerCCSID_, userHandle, IFSLookupReq.OA12, IFSObjAttrs1.OWNERANAME_ASP_FLAS, 0); //@AC7A - ds = (ClientAccessDataStream) server_.sendAndReceive(req); - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream server connection lost."); - connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted"); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } + //create user handle + int userHandle = UNINITIALIZED, objectHandle = UNINITIALIZED; + try + { + // In 7.5 and prior releases, need to create user handle for IFS tables to be initialized. + userHandle = (getSystem().getVRM() <= 0x00070500) ? system_.createUserHandle() : 0; + + try + { + // Issue a Look up request to create an object handle. + IFSLookupReq req = new IFSLookupReq(pathname, preferredServerCCSID_, userHandle, IFSLookupReq.OA12, IFSObjAttrs1.OWNERANAME_ASP_FLAS, 0); //@AC7A + ds = (ClientAccessDataStream) server_.sendAndReceive(req); + } + catch(ConnectionDroppedException e) + { + Trace.log(Trace.ERROR, "Byte stream server connection lost."); + connectionDropped(e); + } + catch(InterruptedException e) + { + Trace.log(Trace.ERROR, "Interrupted"); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; + } - rc = 0; - if (ds instanceof IFSLookupRep) - { - objectHandle = ((IFSLookupRep) ds).getHandle(); - //fileAsp_ = ((IFSLookupRep) ds).getASP(); //@AC7D - retrieveAttributes(ds, objectHandle); //@AC7A - } - else if (ds instanceof IFSReturnCodeRep) - { - rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc != IFSReturnCodeRep.SUCCESS) + rc = 0; + if (ds instanceof IFSLookupRep) + { + objectHandle = ((IFSLookupRep) ds).getHandle(); + retrieveAttributes(ds, objectHandle); //@AC7A + } + else if (ds instanceof IFSReturnCodeRep) + { + rc = ((IFSReturnCodeRep) ds).getReturnCode(); + if (rc != IFSReturnCodeRep.SUCCESS) + Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); + + throw new ExtendedIOException(path_, rc); + } + else + { + // Unknown data stream. + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.getReqRepID()); + throw new InternalErrorException(Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); + } + } + finally { - Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); + if (objectHandle != UNINITIALIZED) + freeHandle(objectHandle); } - throw new ExtendedIOException(path_, rc); - } - else - { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", - ds.getReqRepID()); - throw new - InternalErrorException(Integer.toHexString(ds.getReqRepID()), - InternalErrorException.DATA_STREAM_UNKNOWN); - } - }finally{ - //if(userHandle != UNINITIALIZED) - // freeUserHandle(userHandle); - if(objectHandle != UNINITIALIZED) - freeHandle(objectHandle); } - } - return fileAsp_; + return fileAsp_; } -//@AC7A Start - public String getOwnerNameByUserHandle(boolean forceRetrieve) throws IOException, AS400SecurityException { - Trace.log(Trace.INFORMATION, "Owner Name " + (fileOwnerName_ == null? "is null" : fileOwnerName_)); - isDirectory_ = true; - if (forceRetrieve || fileOwnerName_ == null) { - Trace.log(Trace.INFORMATION, "force retrieve for Owner Name."); - fileOwnerName_ = getOwnerNameByUserHandle(); - } - return fileOwnerName_; + public String getOwnerNameByUserHandle(boolean forceRetrieve) throws IOException, AS400SecurityException + { + Trace.log(Trace.INFORMATION, "Owner Name " + (fileOwnerName_ == null? "is null" : fileOwnerName_)); + isDirectory_ = true; + if (forceRetrieve || fileOwnerName_ == null) + { + Trace.log(Trace.INFORMATION, "force retrieve for Owner Name."); + fileOwnerName_ = getOwnerNameByUserHandle(); + } + + return fileOwnerName_; } -//@AC7A End - public String getOwnerNameByUserHandle() throws IOException, AS400SecurityException { - //String ownerName = null; //@AC7D - ClientAccessDataStream ds = null; - int rc = 0; + public String getOwnerNameByUserHandle() throws IOException, AS400SecurityException + { + ClientAccessDataStream ds = null; + int rc = 0; - // Ensure that we are connected to the server. - connect(); - byte[] pathname = getConverter().stringToByteArray(path_); + // Ensure that we are connected to the server. + connect(); + byte[] pathname = getConverter().stringToByteArray(path_); - //create user handle - int userHandle = UNINITIALIZED, objectHandle = UNINITIALIZED; - try{ - userHandle = system_.createUserHandle(); + //create user handle + int userHandle = UNINITIALIZED, objectHandle = UNINITIALIZED; try { - // Issue a Look up request to create an object handle. - //IFSLookupReq req = new IFSLookupReq(pathname, preferredServerCCSID_, userHandle, IFSLookupReq.OA1, IFSObjAttrs1.OWNER_NAME_FLAG, 0); //@AC7A End - IFSLookupReq req = new IFSLookupReq(pathname, preferredServerCCSID_, userHandle, IFSLookupReq.OA12, IFSObjAttrs1.OWNERANAME_ASP_FLAS, 0); //@AC7A - ds = (ClientAccessDataStream) server_.sendAndReceive(req); - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream server connection lost."); - connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted"); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } + // In 7.5 and prior releases, need to create user handle for IFS tables to be initialized. + userHandle = (getSystem().getVRM() <= 0x00070500) ? system_.createUserHandle() : 0; + + try + { + // Issue a Look up request to create an object handle. + IFSLookupReq req = new IFSLookupReq(pathname, preferredServerCCSID_, userHandle, IFSLookupReq.OA12, IFSObjAttrs1.OWNERANAME_ASP_FLAS, 0); //@AC7A + ds = (ClientAccessDataStream) server_.sendAndReceive(req); + } + catch(ConnectionDroppedException e) + { + Trace.log(Trace.ERROR, "Byte stream server connection lost."); + connectionDropped(e); + } + catch(InterruptedException e) + { + Trace.log(Trace.ERROR, "Interrupted"); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; + } - // Verify that we got a handle back. - rc = 0; - if (ds instanceof IFSLookupRep) - { - //ownerName = ((IFSLookupRep) ds).getOwnerName(system_.getCcsid()); //@AC7A End - objectHandle = ((IFSLookupRep) ds).getHandle(); - retrieveAttributes(ds, objectHandle); //@AC7A - } - else if (ds instanceof IFSReturnCodeRep) - { - rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc != IFSReturnCodeRep.SUCCESS) - { - Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); - } - throw new ExtendedIOException(path_, rc); + // Verify that we got a handle back. + rc = 0; + if (ds instanceof IFSLookupRep) + { + //ownerName = ((IFSLookupRep) ds).getOwnerName(system_.getCcsid()); //@AC7A End + objectHandle = ((IFSLookupRep) ds).getHandle(); + retrieveAttributes(ds, objectHandle); //@AC7A + } + else if (ds instanceof IFSReturnCodeRep) + { + rc = ((IFSReturnCodeRep) ds).getReturnCode(); + if (rc != IFSReturnCodeRep.SUCCESS) Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); + throw new ExtendedIOException(path_, rc); + } + else + { + // Unknown data stream. + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.getReqRepID()); + throw new InternalErrorException(Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); + } } - else + finally { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", - ds.getReqRepID()); - throw new - InternalErrorException(Integer.toHexString(ds.getReqRepID()), - InternalErrorException.DATA_STREAM_UNKNOWN); + if(objectHandle != UNINITIALIZED) + freeHandle(objectHandle); } - }finally{ - // if(userHandle != UNINITIALIZED) - // freeUserHandle(userHandle); - if(objectHandle != UNINITIALIZED) - freeHandle(objectHandle); - } - //return (ownerName == null ? "" : ownerName); //@AC7D - return (fileOwnerName_ == null ? "" : fileOwnerName_); //@AC7A + + return (fileOwnerName_ == null ? "" : fileOwnerName_); //@AC7A } -//@AC7A Start - public String getFileSystemType(boolean isDirectory) throws IOException, AS400SecurityException { - isDirectory_ = isDirectory; - return getFileSystemType(); + public String getFileSystemType(boolean isDirectory) throws IOException, AS400SecurityException + { + isDirectory_ = isDirectory; + return getFileSystemType(); } -//@AC7A End - public String getFileSystemType() throws IOException, AS400SecurityException { - String typeString = "Unknown"; + public String getFileSystemType() throws IOException, AS400SecurityException + { + String typeString = "Unknown"; - if (fileSystemType_ == UNINITIALIZED) - { - ClientAccessDataStream ds = null; - int rc = 0; - connect(); - - int objectHandle = UNINITIALIZED; - byte[] pathname = getConverter().stringToByteArray(path_); + if (fileSystemType_ == UNINITIALIZED) + { + ClientAccessDataStream ds = null; + int rc = 0; + connect(); - //create user handle - int userHandle = UNINITIALIZED; - try{ - userHandle = system_.createUserHandle(); - try - { - // Issue a Look up request to create an object handle. - //IFSLookupReq req = new IFSLookupReq(pathname, preferredServerCCSID_, userHandle); //@AC7D - IFSLookupReq req = new IFSLookupReq(pathname, preferredServerCCSID_, userHandle, IFSLookupReq.OA12, IFSObjAttrs1.OWNERANAME_ASP_FLAS, 0); //@AC7A Start - ds = (ClientAccessDataStream) server_.sendAndReceive(req); - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream server connection lost."); - connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted"); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } + int objectHandle = UNINITIALIZED; + byte[] pathname = getConverter().stringToByteArray(path_); - rc = 0; - if (ds instanceof IFSLookupRep) - { - objectHandle = ((IFSLookupRep) ds).getHandle(); - retrieveAttributes(ds, objectHandle); //@AC7A - } - else if (ds instanceof IFSReturnCodeRep) - { - rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc != IFSReturnCodeRep.SUCCESS) + //create user handle + int userHandle = UNINITIALIZED; + try { - Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); - } - throw new ExtendedIOException(path_, rc); - } - else - { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", - ds.getReqRepID()); - throw new - InternalErrorException(Integer.toHexString(ds.getReqRepID()), - InternalErrorException.DATA_STREAM_UNKNOWN); - } + userHandle = (getSystem().getVRM() <= 0x00070500) ? system_.createUserHandle() : 0; + + try + { + // Issue a Look up request to create an object handle. + IFSLookupReq req = new IFSLookupReq(pathname, preferredServerCCSID_, userHandle, IFSLookupReq.OA12, IFSObjAttrs1.OWNERANAME_ASP_FLAS, 0); + ds = (ClientAccessDataStream) server_.sendAndReceive(req); + } + catch(ConnectionDroppedException e) + { + Trace.log(Trace.ERROR, "Byte stream server connection lost."); + connectionDropped(e); + } + catch(InterruptedException e) + { + Trace.log(Trace.ERROR, "Interrupted"); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; + } - /* //@AC7D Start - ds = null; - try - { - // Issue a get file system request. - IFSGetFileSystemReq req = new IFSGetFileSystemReq(objectHandle, userHandle); - ds = (ClientAccessDataStream) server_.sendAndReceive(req); - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream server connection lost."); - connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted"); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - try { - throwException.initCause(e); - } catch (Throwable t) {} - throw throwException; - } + rc = 0; + if (ds instanceof IFSLookupRep) + { + objectHandle = ((IFSLookupRep) ds).getHandle(); + retrieveAttributes(ds, objectHandle); //@AC7A + } + else if (ds instanceof IFSReturnCodeRep) + { + rc = ((IFSReturnCodeRep) ds).getReturnCode(); + if (rc != IFSReturnCodeRep.SUCCESS) + Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); - // Verify the reply. - rc = 0; - if (ds instanceof IFSGetFileSystemRep) - { - fileSystemType_ = ((IFSGetFileSystemRep) ds).getFileSystemType(); - } - else if (ds instanceof IFSReturnCodeRep) - { - rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc != IFSReturnCodeRep.SUCCESS) + throw new ExtendedIOException(path_, rc); + } + else + { + // Unknown data stream. + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.getReqRepID()); + throw new InternalErrorException(Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); + } + } + finally { - Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); + if (objectHandle != UNINITIALIZED) + freeHandle(objectHandle); } - throw new ExtendedIOException(path_, rc); - } - else - { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", - ds.getReqRepID()); - throw new - InternalErrorException(InternalErrorException.DATA_STREAM_UNKNOWN, - Integer.toHexString(ds.getReqRepID()),null); - } - */ //@AC7D Start - }finally{ - //if(userHandle != UNINITIALIZED) - // freeUserHandle(userHandle); - if(objectHandle != UNINITIALIZED) - freeHandle(objectHandle); } - } - switch(fileSystemType_) { + + switch(fileSystemType_) + { case 1 : typeString = "EPFS"; break; case 2 : typeString = "QDLS"; break; case 3 : typeString = "QSYS"; break; @@ -2067,65 +1912,55 @@ else if (ds instanceof IFSReturnCodeRep) case 13 : typeString = "IEPFS"; break; case 14 : typeString = "ASPQSYS"; break; } + return typeString; } - //@AC7A Start - private void retrieveAttributes(ClientAccessDataStream ds, int objectHandle) throws IOException, AS400SecurityException { - fileAsp_ = ((IFSLookupRep) ds).getASP(); - //if (isDirectory_) { @AE8D - fileOwnerName_ = ((IFSLookupRep) ds).getOwnerName(system_.getCcsid()); - fileDataCCSID_ = ((IFSLookupRep) ds).getCCSID(serverDatastreamLevel_); - //} - int userHandle = system_.getUserHandle(); - int rc = 0; - ds = null; - try - { - // Issue a get file system request. - IFSGetFileSystemReq req = new IFSGetFileSystemReq(objectHandle, userHandle); - ds = (ClientAccessDataStream) server_.sendAndReceive(req); - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream server connection lost."); - connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted"); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } - - // Verify the reply. - rc = 0; - if (ds instanceof IFSGetFileSystemRep) - { - fileSystemType_ = ((IFSGetFileSystemRep) ds).getFileSystemType(); - } - else if (ds instanceof IFSReturnCodeRep) - { - rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc != IFSReturnCodeRep.SUCCESS) - { - Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); - } - throw new ExtendedIOException(path_, rc); - } - else - { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", - ds.getReqRepID()); - throw new - InternalErrorException(InternalErrorException.DATA_STREAM_UNKNOWN, - Integer.toHexString(ds.getReqRepID()),null); - } - } - //@AC7A End + private void retrieveAttributes(ClientAccessDataStream ds, int objectHandle) throws IOException, AS400SecurityException + { + fileAsp_ = ((IFSLookupRep) ds).getASP(); + fileOwnerName_ = ((IFSLookupRep) ds).getOwnerName(system_.getCcsid()); + fileDataCCSID_ = ((IFSLookupRep) ds).getCCSID(serverDatastreamLevel_); + + int userHandle = (getSystem().getVRM() <= 0x00070500) ? system_.getUserHandle() : 0; + + int rc = 0; + ds = null; + try + { + IFSGetFileSystemReq req = new IFSGetFileSystemReq(objectHandle, userHandle); + ds = (ClientAccessDataStream) server_.sendAndReceive(req); + } + catch(ConnectionDroppedException e) + { + Trace.log(Trace.ERROR, "Byte stream server connection lost."); + connectionDropped(e); + } + catch(InterruptedException e) + { + Trace.log(Trace.ERROR, "Interrupted"); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; + } + // Verify the reply. + rc = 0; + if (ds instanceof IFSGetFileSystemRep) + fileSystemType_ = ((IFSGetFileSystemRep) ds).getFileSystemType(); + else if (ds instanceof IFSReturnCodeRep) + { + rc = ((IFSReturnCodeRep) ds).getReturnCode(); + if (rc != IFSReturnCodeRep.SUCCESS) Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); + throw new ExtendedIOException(path_, rc); + } + else + { + // Unknown data stream. + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.getReqRepID()); + throw new InternalErrorException(InternalErrorException.DATA_STREAM_UNKNOWN, Integer.toHexString(ds.getReqRepID()),null); + } + } } diff --git a/src/main/java/com/ibm/as400/access/IFSFileImplRemote.java b/src/main/java/com/ibm/as400/access/IFSFileImplRemote.java index a9797ac20..380f91a64 100644 --- a/src/main/java/com/ibm/as400/access/IFSFileImplRemote.java +++ b/src/main/java/com/ibm/as400/access/IFSFileImplRemote.java @@ -1035,50 +1035,9 @@ public String getOwnerNameByUserHandle() throws IOException, AS400SecurityExcept return fd_.getOwnerNameByUserHandle(); } - //@AC7A Start public String getOwnerNameByUserHandle(boolean forceRetrieve) throws IOException, AS400SecurityException { return fd_.getOwnerNameByUserHandle(forceRetrieve); } - //@AC7A End - - //@RDA @SAD - /** - Returns the ASP that holds the file. - * @throws IOException If an error occurs while communicating with the system. - * @throws AS400SecurityException If a security or authority error occurs. - **/ - /*public int getASP() - throws IOException, AS400SecurityException - { - // Design note: This method demonstrates how to get attributes that are returned in the OA1* structure (as opposed to the OA2). - int ASP = 0; - - fd_.connect(); - // The 'owner name' field is in the OA1 structure; the flag is in the first Flags() field. - try - { - IFSListAttrsRep reply = fd_.listObjAttrs1(IFSObjAttrs1.ASP_FLAG, 0); - if (reply != null) { - ASP = reply.getASP(); - } - else { - if (Trace.traceOn_) Trace.log(Trace.WARNING, "getASP: " + - "IFSReturnCodeRep return code", fd_.errorRC_); - if (fd_.errorRC_ == IFSReturnCodeRep.FILE_NOT_FOUND || - fd_.errorRC_ == IFSReturnCodeRep.PATH_NOT_FOUND) - { - throw new ExtendedIOException(fd_.path_, ExtendedIOException.PATH_NOT_FOUND); - } - } - } - catch (ExtendedIOException e) { - if (e.getReturnCode() == ExtendedIOException.DIR_ENTRY_EXISTS) { - if (Trace.traceOn_) Trace.log(Trace.WARNING, "Unable to determine ASP of directory.", e); - } - else throw e; - } - return ASP; - }*/ //@AC7A Start public int getASP(boolean isDirectory) throws IOException, AS400SecurityException { diff --git a/src/main/java/com/ibm/as400/access/IFSUserHandle2Req.java b/src/main/java/com/ibm/as400/access/IFSUserHandle2Req.java index 086cbac59..d23a3963f 100644 --- a/src/main/java/com/ibm/as400/access/IFSUserHandle2Req.java +++ b/src/main/java/com/ibm/as400/access/IFSUserHandle2Req.java @@ -13,27 +13,48 @@ /////////////////////////////////////////////////////////////////////////////// package com.ibm.as400.access; -public class IFSUserHandle2Req extends IFSDataStreamReq { - private static final int TEMPLATE_LENGTH = 10; +public class IFSUserHandle2Req extends IFSDataStreamReq +{ + private static final int TEMPLATE_LENGTH = 2; private static final int LLCP_LENGTH = 6; - private static final int SERVER_TICKET_LL_OFFSET = 22; - private static final int SERVER_TICKET_CP_OFFSET = 26; - private static final int SERVER_TICKET_OFFSET = 28; IFSUserHandle2Req(byte[] authenticationBytes) { - super(HEADER_LENGTH + TEMPLATE_LENGTH + LLCP_LENGTH + authenticationBytes.length); + this(authenticationBytes, null); + } + + IFSUserHandle2Req(byte[] authenticationBytes, byte[] addAuthFactor) + { + super(HEADER_LENGTH + TEMPLATE_LENGTH + LLCP_LENGTH + authenticationBytes.length + + (null != addAuthFactor && 0 < addAuthFactor.length ? 10 + addAuthFactor.length :0)); setLength(data_.length); setTemplateLen(TEMPLATE_LENGTH); - setReqRepID(0x0023); + setReqRepID(0x002B); - // Set the 'Server Ticket' LL. - set32bit(authenticationBytes.length + LLCP_LENGTH, SERVER_TICKET_LL_OFFSET); - - // Set the 'filename' code point. - set16bit(0x0013, SERVER_TICKET_CP_OFFSET); - - // Set the 'filename' value. - System.arraycopy(authenticationBytes, 0, data_, SERVER_TICKET_OFFSET, authenticationBytes.length); + int offset = 22; + + // Server Ticket + // LL + set32bit(authenticationBytes.length + LLCP_LENGTH, offset); + // CP + set16bit(0x0013, offset + 4); + // Data + System.arraycopy(authenticationBytes, 0, data_, offset + 6, authenticationBytes.length); + + offset += (6 + authenticationBytes.length); + + // Authentication factor + if (addAuthFactor != null && addAuthFactor.length > 0) + { + //LL + set32bit(addAuthFactor.length + 4 + 2 + 4, offset); + // CP + set16bit(0x0015, offset + 4); + // CCSID + set32bit(1208, offset + 6); + // data + System.arraycopy(addAuthFactor, 0, data_, offset + 10, addAuthFactor.length); + + offset += 10 + addAuthFactor.length; + } } - } diff --git a/src/main/java/com/ibm/as400/access/PasswordDialog.java b/src/main/java/com/ibm/as400/access/PasswordDialog.java index f8bc4a493..831a1b588 100644 --- a/src/main/java/com/ibm/as400/access/PasswordDialog.java +++ b/src/main/java/com/ibm/as400/access/PasswordDialog.java @@ -29,21 +29,25 @@ import java.awt.TextField; /** - Provides a dialog for prompting end-users for a system name, a user ID, and/or a password. End-user programs will typically not need to use this class directly. Instead, such programs should allow the AS400 class to display the dialog when necessary. + Provides a dialog for prompting end-users for a system name, a user ID, and/or a password. + End-user programs will typically not need to use this class directly. Instead, such programs + should allow the AS400 class to display the dialog when necessary. @see SignonHandler **/ public class PasswordDialog extends Dialog { static final long serialVersionUID = 4L; // Implementation notes: - // * There is a concern that making this class public makes it too easy for external developers to display a Toolbox signon prompt and gather end-user passwords. The general consensus is that this would be easy enough for most Java developers to do, anyway (without this class)! - // * We are intentionally NOT exposing control over the checkboxes. No reason other than to minimize the public interface. + // -- There is a concern that making this class public makes it too easy for external developers to display a Toolbox signon + // prompt and gather end-user passwords. The general consensus is that this would be easy enough for most Java developers to do, anyway (without this class)! + // -- We are intentionally NOT exposing control over the checkboxes. No reason other than to minimize the public interface. // Private data. private AS400SignonDialogAdapter listener_; private TextField systemNameTextField_; private TextField userIdTextField_; private TextField passwordTextField_; + private TextField additionalFactorTextField_; private Checkbox defaultUserCheckbox_; private Checkbox cachePasswordCheckbox_; private Button okButton_; @@ -56,11 +60,16 @@ public class PasswordDialog extends Dialog **/ public PasswordDialog(Frame parent, String titleText) { - this(parent, titleText, false); + this(parent, titleText, false, false); } PasswordDialog(Frame parent, String titleText, boolean showCheckbox) { + this(parent, titleText, showCheckbox, false); + } + + PasswordDialog(Frame parent, String titleText, boolean showCheckbox, boolean showAdditionalFactor) + { super(parent, titleText, true); listener_ = new AS400SignonDialogAdapter(this); @@ -72,42 +81,51 @@ public PasswordDialog(Frame parent, String titleText) constraints.insets = new Insets(8, 8, 0, 8); setLayout(layout); - setResizable(false); + setResizable(true); // Set the background color to light gray. setBackground(Color.lightGray); - // Create the 'System:' Label and add to the panel. + // Create the 'System:' Label and text field Label label = new Label(ResourceBundleLoader.getCoreText("DLG_SYSTEM_LABEL"), Label.LEFT); add(label, layout, constraints, 0, 0, 1, 1); - // Create the system text field and add to the panel. systemNameTextField_ = new TextField(10); systemNameTextField_.addFocusListener(listener_); systemNameTextField_.addKeyListener(listener_); add(systemNameTextField_, layout, constraints, 1, 0, 1, 1); - // Create the 'User ID:' Label and add to the panel. + // Create the 'User ID:' Label and text field label = new Label(ResourceBundleLoader.getCoreText("DLG_USER_ID_LABEL"), Label.LEFT); add(label, layout, constraints, 0, 1, 1, 1); - // Create the user id text field and add to the panel. userIdTextField_ = new AS400SignonTextField(); userIdTextField_.addFocusListener(listener_); userIdTextField_.addKeyListener(listener_); add(userIdTextField_, layout, constraints, 1, 1, 1, 1); - // Create the 'Password:' Label and add to the panel. + // Create the 'Password:' Label and text field label = new Label(ResourceBundleLoader.getCoreText("DLG_PASSWORD_LABEL"), Label.LEFT); add(label, layout, constraints, 0, 2, 1, 1); - // Create the password text field and add to the panel. passwordTextField_ = new TextField(10); passwordTextField_.setEchoChar('*'); passwordTextField_.addFocusListener(listener_); passwordTextField_.addKeyListener(listener_); add(passwordTextField_, layout, constraints, 1, 2, 1, 1); + // Create additional factor label and field if requested + if (showAdditionalFactor) + { + label = new Label(ResourceBundleLoader.getCoreText("DLG_ADDITIONAL_FACTOR_LABEL"), Label.LEFT); + add(label, layout, constraints, 0, 3, 1, 1); + + additionalFactorTextField_ = new TextField(10); + additionalFactorTextField_.addFocusListener(listener_); + additionalFactorTextField_.addKeyListener(listener_); + add(additionalFactorTextField_, layout, constraints, 1, 3, 1, 1); + } + // Create the default checkbox. defaultUserCheckbox_ = new Checkbox(ResourceBundleLoader.getCoreText("DLG_DEFAULT_PASSWORD_CHECK_BOX")); defaultUserCheckbox_.addFocusListener(listener_); @@ -122,7 +140,8 @@ public PasswordDialog(Frame parent, String titleText) // Create panels to hold the checkboxes. Panel centeringPanel = new Panel(); centeringPanel.setLayout(new FlowLayout(FlowLayout.CENTER)); - add(centeringPanel, layout, constraints, 0, 3, 2, 2); + add(centeringPanel, layout, constraints, 0, showAdditionalFactor ? 4 : 3, 2, 2); + Panel checkboxPanel = new Panel(); checkboxPanel.setLayout(new GridLayout(2, 1, 2, 2)); centeringPanel.add(checkboxPanel); @@ -138,7 +157,8 @@ public PasswordDialog(Frame parent, String titleText) Panel centeringPanel = new Panel(); centeringPanel.setLayout(new FlowLayout(FlowLayout.CENTER)); constraints.insets = new Insets(8, 8, 8, 8); - add(centeringPanel, layout, constraints, 0, 5, 2, 1); + add(centeringPanel, layout, constraints, 0, showAdditionalFactor ? 6 : 5, 2, 1); + Panel buttonPanel = new Panel(); buttonPanel.setLayout(new GridLayout(1, 2, 8, 0)); centeringPanel.add(buttonPanel); @@ -149,6 +169,7 @@ public PasswordDialog(Frame parent, String titleText) okButton_.addFocusListener(listener_); okButton_.addKeyListener(listener_); buttonPanel.add(okButton_); + cancelButton_ = new Button(ResourceBundleLoader.getCoreText("DLG_CANCEL_BUTTON")); cancelButton_.addActionListener(listener_); cancelButton_.addFocusListener(listener_); @@ -225,6 +246,15 @@ public String getSystemName() { return systemNameTextField_.getText(); } + + /** + Returns the additional factor. + @return The additional factor. + **/ + public String getAdditionalFactor() + { + return additionalFactorTextField_ != null ? additionalFactorTextField_.getText() : ""; + } /** Returns the user ID. @@ -271,6 +301,8 @@ public void setUserId(String userId) boolean prompt() { passwordTextField_.setText(""); + if (additionalFactorTextField_ != null) + additionalFactorTextField_.setText(""); // Start the focus in the appropriate field. if (getSystemName().length() == 0) diff --git a/src/main/java/com/ibm/as400/access/ProfileTokenImplNative.java b/src/main/java/com/ibm/as400/access/ProfileTokenImplNative.java index 45fa53a49..fb9be876c 100644 --- a/src/main/java/com/ibm/as400/access/ProfileTokenImplNative.java +++ b/src/main/java/com/ibm/as400/access/ProfileTokenImplNative.java @@ -14,6 +14,8 @@ package com.ibm.as400.access; +import java.io.IOException; + import com.ibm.as400.security.auth.*; /** @@ -116,53 +118,12 @@ public byte[] generateToken(String uid, char[] pwd, int type, int timeoutInterva return nativeCreateTokenChar(uid.toUpperCase(), pwd, type, timeoutInterval); } - - - /** - * Generates and returns a new profile token based on - * the provided information using a password special value. - * - * @param uid - * The name of the user profile for which the token - * is to be generated. - * - * @param pwdSpecialValue - * A password special value. - * Possible types are defined as fields on the - * ProfileTokenCredential class: - *

- *

- * - * @param type - * The type of token. - * Possible types are defined as fields on the - * ProfileTokenCredential class: - *

- *

- * - * @param timeoutInterval - * The number of seconds to expiration. - * - * @return - * The token bytes. - * - * @exception RetrieveFailedException - * If errors occur while generating the token. - * - */ - public byte[] generateToken(String uid, int pwdSpecialValue, int type, - int timeoutInterval) throws RetrieveFailedException { - + @Override + public byte[] generateToken(String uid, int pwdSpecialValue, int type, int timeoutInterval) throws RetrieveFailedException { // Convert password special value from int to string String pwdSpecialVal; - switch(pwdSpecialValue) { + switch(pwdSpecialValue) + { case ProfileTokenCredential.PW_NOPWD: pwdSpecialVal = ProfileTokenImpl.PW_STR_NOPWD; break; @@ -170,51 +131,47 @@ public byte[] generateToken(String uid, int pwdSpecialValue, int type, pwdSpecialVal = ProfileTokenImpl.PW_STR_NOPWDCHK; break; default: - Trace.log(Trace.ERROR, "Password special value = " + - pwdSpecialValue + " is not valid."); - throw new ExtendedIllegalArgumentException( - "password special value", - ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); + Trace.log(Trace.ERROR, "Password special value = " + pwdSpecialValue + " is not valid."); + throw new ExtendedIllegalArgumentException("password special value", ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); } - // Call native method and return token bytes - return nativeCreateTokenChar( - uid.toUpperCase(), pwdSpecialVal.toCharArray(), type, timeoutInterval); + // Call native method and return token bytes, we rely on the fact this class is only called if running on AS400. + return nativeCreateTokenChar(uid.toUpperCase(), pwdSpecialVal.toCharArray(), type, timeoutInterval); } /** * Generates and returns a new profile token based on * the provided information using a password string. - * + * * @deprecated Use {@link #generateTokenExtended(String,char[],int,int)} * * @param uid - * The name of the user profile for which the token - * is to be generated. + * The name of the user profile for which the token + * is to be generated. * * @param pwd - * The user profile password (encoded). + * The user profile password (encoded). * Special values are not supported by this method. * * @param type - * The type of token. - * Possible types are defined as fields on the + * The type of token. + * Possible types are defined as fields on the * ProfileTokenCredential class: - *

- *

+ *

+ *

* * @param timeoutInterval * The number of seconds to expiration. * * @return - * The token bytes. + * The token bytes. * * @exception RetrieveFailedException - * If errors occur while generating the token. + * If errors occur while generating the token. * */ @Deprecated @@ -222,131 +179,75 @@ public byte[] generateTokenExtended(String uid, String pwd, int type, int timeou { char[] passwordChars = (pwd == null) ? null : pwd.toCharArray(); - try { + try { return generateTokenExtended(uid, passwordChars, type, timeoutInterval); } finally { AS400Credential.clearArray(passwordChars); - } - } - - - /** - * Generates and returns a new profile token based on - * the provided information using a password string. - * - * @param uid - * The name of the user profile for which the token - * is to be generated. - * - * @param pwd - * The user profile password (encoded). - * Special values are not supported by this method. - * - * @param type - * The type of token. - * Possible types are defined as fields on the - * ProfileTokenCredential class: - *

- *

- * - * @param timeoutInterval - * The number of seconds to expiration. - * - * @return - * The token bytes. - * - * @exception RetrieveFailedException - * If errors occur while generating the token. - * - */ - public byte[] generateTokenExtended(String uid, char [] pwd, int type, - int timeoutInterval) throws RetrieveFailedException { + } + } - AS400 sys = getCredential().getSystem(); + @Override + public byte[] generateTokenExtended(String uid, char [] pwd, int type, int timeoutInterval) throws RetrieveFailedException { + AS400 sys = getCredential().getSystem(); - ProgramParameter[] parmlist = new ProgramParameter[8]; + // Setup parameters + ProgramParameter[] parmlist = new ProgramParameter[8]; - // Output: Profile token. - parmlist[0] = new ProgramParameter( - ProfileTokenCredential.TOKEN_LENGTH); + // Output: Profile token. + parmlist[0] = new ProgramParameter(ProfileTokenCredential.TOKEN_LENGTH); // Input: User profile name. Uppercase, get bytes (ccsid 37). try { - parmlist[1] = new ProgramParameter( - SignonConverter.stringToByteArray(uid.toUpperCase())); + parmlist[1] = new ProgramParameter(SignonConverter.stringToByteArray(uid.toUpperCase())); } catch (AS400SecurityException se) { throw new RetrieveFailedException(se.getReturnCode()); } - // Input: User password. String to char[], char[] to byte[] (unicode). - parmlist[2] = new ProgramParameter( - BinaryConverter.charArrayToByteArray(pwd)); - - // Input: Time out interval. Int to byte[]. - parmlist[3] = new ProgramParameter( - BinaryConverter.intToByteArray(timeoutInterval)); - - // Input: Profile token type. Int to string, get bytes. - parmlist[4] = new ProgramParameter( - CharConverter.stringToByteArray( - sys, Integer.toString(type))); - - // Input/output: Error code. NULL. - parmlist[5] = new ProgramParameter( - BinaryConverter.intToByteArray(0)); - - // Input: Length of user password. Int to byte[]. - parmlist[6] = new ProgramParameter( - BinaryConverter.intToByteArray( - parmlist[2].getInputData().length)); - - // Input: CCSID of user password. Int to byte[]. Unicode = 13488. - parmlist[7] = new ProgramParameter( - BinaryConverter.intToByteArray(13488)); - - ProgramCall programCall = new ProgramCall(sys); - - try { - programCall.setProgram( - QSYSObjectPathName.toPath( - "QSYS", "QSYGENPT", "PGM"), parmlist); - programCall.suggestThreadsafe(); // Run on-thread if possible; allows app to use disabled profile. - if (!programCall.run()) { - Trace.log(Trace.ERROR, "Call to QSYGENPT failed."); - throw new RetrieveFailedException( - programCall.getMessageList()); + // Input: User password. String to char[], char[] to byte[] (unicode). + parmlist[2] = new ProgramParameter(BinaryConverter.charArrayToByteArray(pwd)); + + // Input: Time out interval. Int to byte[]. + parmlist[3] = new ProgramParameter(BinaryConverter.intToByteArray(timeoutInterval)); + + // Input: Profile token type. Int to string, get bytes. + parmlist[4] = new ProgramParameter(CharConverter.stringToByteArray(sys, Integer.toString(type))); + + // Input/output: Error code. NULL. + parmlist[5] = new ProgramParameter(BinaryConverter.intToByteArray(0)); + + // Input: Length of user password. Int to byte[]. + parmlist[6] = new ProgramParameter(BinaryConverter.intToByteArray(parmlist[2].getInputData().length)); + + // Input: CCSID of user password. Int to byte[]. Unicode = 13488. + parmlist[7] = new ProgramParameter(BinaryConverter.intToByteArray(13488)); + + ProgramCall programCall = new ProgramCall(sys); + + try + { + programCall.setProgram(QSYSObjectPathName.toPath("QSYS", "QSYGENPT", "PGM"), parmlist); + programCall.suggestThreadsafe(); // Run on-thread if possible; allows app to use disabled profile. + if (!programCall.run()) + { + Trace.log(Trace.ERROR, "Call to QSYGENPT failed."); + throw new RetrieveFailedException(programCall.getMessageList()); + } + } + catch (RetrieveFailedException e) { + throw e; + } + catch (java.io.IOException|java.beans.PropertyVetoException|InterruptedException e) { + Trace.log(Trace.ERROR, "Unexpected Exception: ", e); + throw new InternalErrorException(InternalErrorException.UNEXPECTED_EXCEPTION); + } + catch (Exception e) { + Trace.log(Trace.ERROR, "Unexpected Exception: ", e); + throw new RetrieveFailedException(); } - } - catch (RetrieveFailedException e) { - throw e; // just rethrow - } - catch (java.io.IOException ioe) { - Trace.log(Trace.ERROR, "Unexpected IOException: ", ioe); - throw new InternalErrorException( - InternalErrorException.UNEXPECTED_EXCEPTION); - } - catch (java.beans.PropertyVetoException pve) { - Trace.log(Trace.ERROR, "Unexpected PropertyVetoException: ", pve); - throw new InternalErrorException( - InternalErrorException.UNEXPECTED_EXCEPTION); - } - catch (InterruptedException ine) { - Trace.log(Trace.ERROR, "Unexpected InterruptedException: ", ine); - throw new InternalErrorException( - InternalErrorException.UNEXPECTED_EXCEPTION); - } - catch (Exception e) { - Trace.log(Trace.ERROR, "Unexpected Exception: ", e); - throw new RetrieveFailedException(); - } - return parmlist[0].getOutputData(); - } + return parmlist[0].getOutputData(); + } // Returns the credential delegating behavior to the implementation // object. @@ -378,7 +279,7 @@ public boolean isCurrent() } } - /** + /** * Generates and returns a new profile token based on a user profile and * password special value. * @@ -405,7 +306,7 @@ public boolean isCurrent() * * @deprecated Use {@link #nativeCreateToken(String,char[],int,int)} */ - @Deprecated + @Deprecated native byte[] nativeCreateToken( String user, String password, @@ -436,8 +337,8 @@ native byte[] nativeCreateToken( // TODO: Write native code in /osxpf/v7r5m0.xpf/cur/cmvc/base.pgm/yjsp.xpf native byte[] nativeCreateTokenChar( - String user, - char[] password, + String user, + char[] password, int type, int timeoutInterval) throws RetrieveFailedException; @@ -463,7 +364,7 @@ native int nativeGetTimeToExpiration( // @param timeoutInterval The number of seconds before expiration. // @exception RefreshFailedException If errors occur during refresh. native void nativeRefreshToken( - byte[] token, + byte[] token, int type, int timeoutInterval) throws RefreshFailedException; diff --git a/src/main/java/com/ibm/as400/access/ProfileTokenVault.java b/src/main/java/com/ibm/as400/access/ProfileTokenVault.java index 3993ae651..67dfd4107 100644 --- a/src/main/java/com/ibm/as400/access/ProfileTokenVault.java +++ b/src/main/java/com/ibm/as400/access/ProfileTokenVault.java @@ -98,6 +98,15 @@ protected int getType() { public void storeProfileTokenCredential(ProfileTokenCredential credential) { this.profileTokenCredential_ = credential; } + + /** + * Retrieve ProfileTokenCredential object in vault if one exists. + * + * @return The ProfileTokenCredential object or null. + */ + public ProfileTokenCredential getProfileTokenCredential() { + return profileTokenCredential_; + } /** * Retrieves unencoded credential from a vault diff --git a/src/main/java/com/ibm/as400/access/ProgramParameter.java b/src/main/java/com/ibm/as400/access/ProgramParameter.java index 3ed8ac168..42e9cd3f3 100644 --- a/src/main/java/com/ibm/as400/access/ProgramParameter.java +++ b/src/main/java/com/ibm/as400/access/ProgramParameter.java @@ -23,7 +23,10 @@ import java.io.Serializable; /** - Used with {@link ProgramCall ProgramCall} and {@link ServiceProgramCall ServiceProgramCall} to pass parameter data, either to a program, from a program, or both. Input data is passed to a program as a byte array with {@link #setInputData setInputData()}. Output data is requested from a program by specifying the amount of data to return with {@link #setOutputDataLength setOutputDataLength()}. To get the output data once the program has run, use {@link #getOutputData getOutputData()}. These values may also be set on the constructor. + Used with {@link ProgramCall ProgramCall} and {@link ServiceProgramCall ServiceProgramCall} to pass parameter data, either to a program, + from a program, or both. Input data is passed to a program as a byte array with {@link #setInputData setInputData()}. + Output data is requested from a program by specifying the amount of data to return with {@link #setOutputDataLength setOutputDataLength()}. + To get the output data once the program has run, use {@link #getOutputData getOutputData()}. These values may also be set on the constructor. **/ public class ProgramParameter implements Serializable { diff --git a/src/main/java/com/ibm/as400/access/SignonInfoReq.java b/src/main/java/com/ibm/as400/access/SignonInfoReq.java index 5fc327d22..09f33d9c8 100644 --- a/src/main/java/com/ibm/as400/access/SignonInfoReq.java +++ b/src/main/java/com/ibm/as400/access/SignonInfoReq.java @@ -16,10 +16,11 @@ import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; class SignonInfoReq extends ClientAccessDataStream { - SignonInfoReq(byte[] userIDbytes, byte[] authenticationBytes, int authScheme, int serverLevel, char[] addAuthFactor) + SignonInfoReq(byte[] userIDbytes, byte[] authenticationBytes, int authScheme, int serverLevel, byte[] addAuthFactor) { super(new byte[37 + authenticationBytes.length + (userIDbytes == null ? 0 : 16) + (serverLevel < 5 ? 0 : 7) + (serverLevel >= 18 && null != addAuthFactor && 0 < addAuthFactor.length ? 10 + addAuthFactor.length :0)]); @@ -101,30 +102,21 @@ else if (authenticationBytes.length == 20) if (serverLevel >= 18 && null != addAuthFactor && 0 < addAuthFactor.length) { - byte[] aafBytes; - try { - aafBytes = new String(addAuthFactor).getBytes("UTF-8"); - } - catch (UnsupportedEncodingException e) { - // should never happen - Trace.log(Trace.ERROR, e); - throw new InternalErrorException(InternalErrorException.UNEXPECTED_EXCEPTION, e); - } - //LL - set32bit(aafBytes.length + 4 + 2 + 4, offset); + set32bit(addAuthFactor.length + 4 + 2 + 4, offset); // CP set16bit(0x112F, offset + 4); // CCSID set32bit(1208, offset + 6); // data - System.arraycopy(aafBytes, 0, data_, offset + 10, aafBytes.length); + System.arraycopy(addAuthFactor, 0, data_, offset + 10, addAuthFactor.length); - offset += 10 + aafBytes.length; + offset += 10 + addAuthFactor.length; } } } + @Override void write(OutputStream out) throws IOException { if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Sending retrieve signon information request..."); diff --git a/src/main/java/com/ibm/as400/access/ToolboxSignonHandler.java b/src/main/java/com/ibm/as400/access/ToolboxSignonHandler.java index 8ee316c0b..fecd451e4 100644 --- a/src/main/java/com/ibm/as400/access/ToolboxSignonHandler.java +++ b/src/main/java/com/ibm/as400/access/ToolboxSignonHandler.java @@ -16,661 +16,703 @@ import java.awt.Frame; import java.io.IOException; import java.beans.PropertyVetoException; -import java.net.UnknownHostException; /** - The Toolbox's default implementation of the SignonHandler interface. - The {@link AS400 AS400} class uses a SignonHandler if additional information - (such as userID or password) must be gathered at runtime - when connecting to the server. + * The Toolbox's default implementation of the SignonHandler interface. The + * {@link AS400 AS400} class uses a SignonHandler if additional information + * (such as userID or password) must be gathered at runtime when connecting to + * the server. **/ final class ToolboxSignonHandler extends SignonHandlerAdapter { - private static final boolean DEBUG = false; - private static final boolean PASSWORD_TRACE = false; - - private String systemName_ = ""; - private String userId_ = ""; - private boolean changingPassword_ = false; - - - - /** - Gathers any missing sign-on information. - If GUI is available, displays an interactive sign-on dialog to the user, with fields for systemName, userID, and password, along with "OK" and "CANCEL" buttons. - Otherwise, simply returns true. - @param event The sign-on event. - @param forceUpdate true indicates that the sign-on information is known to be incomplete or incorrect. false indicates that the information may be correct. - @return true if sign-on should proceed, false if sign-on should not proceed. - **/ - public boolean connectionInitiated(SignonEvent event, boolean forceUpdate) - { - if (DEBUG) System.out.println("ToolboxSignonHandler.connectionInitiated("+forceUpdate+")"); - - return handleSignon((AS400)event.getSource(), forceUpdate, false); - } - - - /** - Handles an exception that was thrown during a sign-on attempt. - If the handler cannot deal with the exception, the handler rethrows exc. - @param event The sign-on event. - @exception AS400SecurityException If the handler cannot handle the exception. - **/ - public void exceptionOccurred(SignonEvent event) - throws AS400SecurityException - { - if (DEBUG) System.out.println("ToolboxSignonHandler.exceptionOccurred()"); - - AS400SecurityException exc = event.getException(); - AS400 system = (AS400)event.getSource(); - if (!system.isGuiAvailable()) throw exc; // do nothing, rethrow the exception - - handleException(system, exc); - } - - - /** - Displays a message warning that the password will expire in daysUntilExpiration days, and asks the userif they would like to change the password. - If user clicks OK, then a "change password" - dialog is displayed, prompting user for old and new passwords. - Otherwise, simply returns true. - @param event The sign-on event. - @return true - **/ - public boolean passwordAboutToExpire(SignonEvent event, int daysUntilExpiration) - { - if (DEBUG) System.out.println("ToolboxSignonHandler.passwordAboutToExpire(" + daysUntilExpiration + ")"); - - AS400 system = (AS400)event.getSource(); - if (!system.isGuiAvailable()) return true; // do nothing, proceed with sign-on - - boolean response = displayMessage(ResourceBundleLoader.substitute(ResourceBundleLoader.getText("DLG_PASSWORD_EXP_WARNING"), Integer.toString(daysUntilExpiration)) + " " + ResourceBundleLoader.getText("DLG_CHANGE_PASSWORD_PROMPT"), ResourceBundleLoader.getText("DLG_SIGNON_TITLE"), true); - if (response) + private static final boolean DEBUG = false; + private static final boolean PASSWORD_TRACE = false; + + private String systemName_ = ""; + private String userId_ = ""; + private boolean changingPassword_ = false; + + /** + * Gathers any missing sign-on information. If GUI is available, displays an + * interactive sign-on dialog to the user, with fields for systemName, userID, + * and password, along with "OK" and "CANCEL" buttons. Otherwise, simply returns + * true. + * + * @param event The sign-on event. + * @param forceUpdate true indicates that the sign-on information is + * known to be incomplete or incorrect. false + * indicates that the information may be correct. + * @return true if sign-on should proceed, false if sign-on should not proceed. + **/ + @Override + public boolean connectionInitiated(SignonEvent event, boolean forceUpdate) { - handlePasswordChange(system); // tolerate cancellation of the password change - } - return true; // do nothing, proceed with sign-on - } - - - /** - Displays a message indicating that the password has expired, and asks the user - if they would like to change the password. If user clicks OK, then a "change password" - dialog is displayed, prompting user for old and new passwords. - @param event The sign-on event. - @return true if user clicks OK, false if user clicks Cancel. - **/ - public boolean passwordExpired(SignonEvent event) - { - if (DEBUG) System.out.println("ToolboxSignonHandler.passwordExpired()"); - - AS400 system = (AS400)event.getSource(); - if (!system.isGuiAvailable()) return noGuiAvailable(); - - // See if user wants to change password. - boolean response = displayMessage(ResourceBundleLoader.getText("EXC_PASSWORD_EXPIRED") + "\n" + ResourceBundleLoader.getText("DLG_CHANGE_PASSWORD_PROMPT"), ResourceBundleLoader.getText("DLG_SIGNON_TITLE"), true); - if (response) // User wants to change password. - { - return handlePasswordChange(system); + if (DEBUG) System.out.println("ToolboxSignonHandler.connectionInitiated("+forceUpdate+")"); + + return handleSignon((AS400)event.getSource(), forceUpdate, false); } - else // User canceled the password change. + + /** + * Handles an exception that was thrown during a sign-on attempt. If the handler + * cannot deal with the exception, the handler rethrows exc. + * + * @param event The sign-on event. + * @exception AS400SecurityException If the handler cannot handle the exception. + **/ + @Override + public void exceptionOccurred(SignonEvent event) throws AS400SecurityException { - return false; + if (DEBUG) System.out.println("ToolboxSignonHandler.exceptionOccurred()"); + + AS400SecurityException exc = event.getException(); + AS400 system = (AS400)event.getSource(); + if (!system.isGuiAvailable()) throw exc; // do nothing, rethrow the exception + + handleException(system, exc); } - } - - - /** - Displays a message indicating that the password is incorrect, - and redisplays the sign-on dialog. - @param event The sign-on event. - @return true if user clicks OK, false if user clicks Cancel. - **/ - public boolean passwordIncorrect(SignonEvent event) - { - if (DEBUG) System.out.println("ToolboxSignonHandler.passwordIncorrect()"); - - AS400 system = (AS400)event.getSource(); - if (!system.isGuiAvailable()) return noGuiAvailable(); - displayMessage(ResourceBundleLoader.getText("EXC_PASSWORD_INCORRECT"), - ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); - return handleSignon(system, true, false); - } - - - /** - Displays a message indicating that the password length is incorrect, - and redisplays the sign-on dialog. - @param event The sign-on event. - @return true if user clicks OK, false if user clicks Cancel. - **/ - public boolean passwordLengthIncorrect(SignonEvent event) - { - if (DEBUG) System.out.println("ToolboxSignonHandler.passwordLengthIncorrect()"); - - AS400 system = (AS400)event.getSource(); - if (!system.isGuiAvailable()) return noGuiAvailable(); - displayMessage(ResourceBundleLoader.getText("EXC_PASSWORD_LENGTH_NOT_VALID"), - ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); - return handleSignon(system, true, false); - } - - - /** - Displays a message indicating that the password was not specified, - and redisplays the sign-on dialog. - @param event The sign-on event. - @return true if user clicks OK, false if user clicks Cancel. - **/ - public boolean passwordMissing(SignonEvent event) - { - if (DEBUG) System.out.println("ToolboxSignonHandler.passwordMissing()"); - - AS400 system = (AS400)event.getSource(); - if (!system.isGuiAvailable()) return noGuiAvailable(); - displayMessage(ResourceBundleLoader.getText("DLG_MISSING_PASSWORD"), - ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); - return connectionInitiated(event, true); - } - - - /** - Displays a message indicating that the system name was not specified, - and redisplays the sign-on dialog. - @param event The sign-on event. - @return true if user clicks OK, false if user clicks Cancel. - **/ - public boolean systemNameMissing(SignonEvent event) - { - if (DEBUG) System.out.println("ToolboxSignonHandler.systemNameMissing()"); - - AS400 system = (AS400)event.getSource(); - if (!system.isGuiAvailable()) return noGuiAvailable(); - displayMessage(ResourceBundleLoader.getText("DLG_MISSING_USERID"), // generic MRI - ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); - return handleSignon(system, true, true); - } + /** + * Displays a message warning that the password will expire in + * daysUntilExpiration days, and asks the userif they would like to + * change the password. If user clicks OK, then a "change password" dialog is + * displayed, prompting user for old and new passwords. Otherwise, simply + * returns true. + * + * @param event The sign-on event. + * @return true + **/ + @Override + public boolean passwordAboutToExpire(SignonEvent event, int daysUntilExpiration) + { + if (DEBUG) System.out.println("ToolboxSignonHandler.passwordAboutToExpire(" + daysUntilExpiration + ")"); - // Design Note: In order to preserve historical default behavior, this class does not implement the systemNameUnknown() method. If an unknown system name is specified, an UnknownHostException will be thrown. + AS400 system = (AS400)event.getSource(); + if (!system.isGuiAvailable()) return true; // do nothing, proceed with sign-on + boolean response = displayMessage(ResourceBundleLoader.substitute(ResourceBundleLoader.getText("DLG_PASSWORD_EXP_WARNING"), Integer.toString(daysUntilExpiration)) + " " + ResourceBundleLoader.getText("DLG_CHANGE_PASSWORD_PROMPT"), + ResourceBundleLoader.getText("DLG_SIGNON_TITLE"), true); + if (response) + handlePasswordChange(system); // tolerate cancellation of the password change - /** - Displays a message indicating that the user profile will be disabled if next sign-on attempt is incorrect, - and redisplays the sign-on dialog. - @param event The sign-on event. - @return true if user clicks OK, false if user clicks Cancel. - **/ - public boolean userIdAboutToBeDisabled(SignonEvent event) - { - if (DEBUG) System.out.println("ToolboxSignonHandler.userIdAboutToBeDisabled()"); + return true; // do nothing, proceed with sign-on + } - AS400 system = (AS400)event.getSource(); - if (!system.isGuiAvailable()) return noGuiAvailable(); - displayMessage(ResourceBundleLoader.getText("EXC_PASSWORD_INCORRECT_USERID_DISABLE"), - ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); - return handleSignon(system, true, false); - } - - - /** - Displays a message warning that the system object already has a default user assigned. - @param event The sign-on event. - @param defaultUser The current default user. - @return true - **/ - public boolean userIdDefaultAlreadyAssigned(SignonEvent event, String defaultUser) - { - if (DEBUG) System.out.println("ToolboxSignonHandler.userIdDefaultAlreadyAssigned()"); - - // Put up an informational message, and proceed with sign-on. - displayMessage(ResourceBundleLoader.getText("DLG_DEFAULT_USER_EXISTS"), - ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); - displayMessage(ResourceBundleLoader.getText("DLG_SET_DEFAULT_USER_FAILED"), - ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); - return true; - } - - - /** - Displays a message indicating that the user profile is disabled, - and redisplays the sign-on dialog. - @param event The sign-on event. - @return true if user clicks OK, false if user clicks Cancel. - **/ - public boolean userIdDisabled(SignonEvent event) - { - if (DEBUG) System.out.println("ToolboxSignonHandler.userIdDisabled()"); - - AS400 system = (AS400)event.getSource(); - if (!system.isGuiAvailable()) return noGuiAvailable(); - displayMessage(ResourceBundleLoader.getText("EXC_USERID_DISABLE"), - ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); - return handleSignon(system, true, false); - } - - - /** - Displays a message indicating that the user ID length is incorrect, - and redisplays the sign-on dialog. - @param event The sign-on event. - @return true if user clicks OK, false if user clicks Cancel. - **/ - public boolean userIdLengthIncorrect(SignonEvent event) - { - if (DEBUG) System.out.println("ToolboxSignonHandler.userIdLengthIncorrect()"); - - AS400 system = (AS400)event.getSource(); - if (!system.isGuiAvailable()) return noGuiAvailable(); - displayMessage(ResourceBundleLoader.getText("EXC_USERID_LENGTH_NOT_VALID"), - ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); - return handleSignon(system, true, false); - } - - - /** - Displays a message indicating that the user name was not specified, - and redisplays the sign-on dialog. - @param event The sign-on event. - @return true if user clicks OK, false if user clicks Cancel. - **/ - public boolean userIdMissing(SignonEvent event) - { - if (DEBUG) System.out.println("ToolboxSignonHandler.userIdMissing()"); - - AS400 system = (AS400)event.getSource(); - if (!system.isGuiAvailable()) return noGuiAvailable(); - displayMessage(ResourceBundleLoader.getText("DLG_MISSING_USERID"), - ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); - return handleSignon(system, true, false); - } - - - /** - Displays a message indicating that the specified user ID is unknown, - and redisplays the sign-on dialog. - @param event The sign-on event. - @return true if user clicks OK, false if user clicks Cancel. - **/ - public boolean userIdUnknown(SignonEvent event) - { - if (DEBUG) System.out.println("ToolboxSignonHandler.userIdUnknown()"); - - AS400 system = (AS400)event.getSource(); - if (!system.isGuiAvailable()) return noGuiAvailable(); - displayMessage(ResourceBundleLoader.getText("EXC_USERID_UNKNOWN"), - ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); - return handleSignon(system, true, false); - } - - - // - // - // Private utility methods. - // - // - - - - /** - Displays an informational dialog to the user. - @param message The message text to display. - @param dialogTitle The title for the dialog. - **/ - private void displayMessage(String message, String dialogTitle) - { - displayMessage(message, dialogTitle, false); - } - - - /** - Displays an informational dialog to the user. - @param message The message text to display. - @param dialogTitle The title for the dialog. - @param getResponse Whether to get response from user. - @return The response from the user. true if user indicated approval, false otherwise. - **/ - private boolean displayMessage(String message, String dialogTitle, boolean getResponse) - { - MessageDialog md = new MessageDialog(new Frame(), message, dialogTitle, getResponse); - return md.display(); - } - - - /** - Handles an exception that was thrown during a sign-on attempt. - If the handler cannot deal with the exception, the handler rethrows exc. - @param system The system. - @param exc The exception. - @exception AS400SecurityException If the handler cannot handle the exception. - **/ - private void handleException(AS400 system, AS400SecurityException exc) - throws AS400SecurityException - { - switch (exc.getReturnCode()) + /** + * Displays a message indicating that the password has expired, and asks the + * user if they would like to change the password. If user clicks OK, then a + * "change password" dialog is displayed, prompting user for old and new + * passwords. + * + * @param event The sign-on event. + * @return true if user clicks OK, false if user clicks Cancel. + **/ + @Override + public boolean passwordExpired(SignonEvent event) { - case AS400SecurityException.USERID_LENGTH_NOT_VALID: - case AS400SecurityException.PASSWORD_LENGTH_NOT_VALID: - case AS400SecurityException.USERID_DISABLE: - case AS400SecurityException.PASSWORD_INCORRECT: - case AS400SecurityException.PASSWORD_INCORRECT_USERID_DISABLE: - case AS400SecurityException.SIGNON_REQUEST_NOT_VALID: - case AS400SecurityException.USERID_UNKNOWN: - case AS400SecurityException.SIGNON_CHAR_NOT_VALID: - - case AS400SecurityException.PASSWORD_CHANGE_REQUEST_NOT_VALID: - case AS400SecurityException.PASSWORD_OLD_NOT_VALID: - case AS400SecurityException.PASSWORD_NEW_NOT_VALID: - case AS400SecurityException.PASSWORD_NEW_TOO_LONG: - case AS400SecurityException.PASSWORD_NEW_TOO_SHORT: - case AS400SecurityException.PASSWORD_NEW_REPEAT_CHARACTER: - case AS400SecurityException.PASSWORD_NEW_ADJACENT_DIGITS: - case AS400SecurityException.PASSWORD_NEW_CONSECUTIVE_REPEAT_CHARACTER: - case AS400SecurityException.PASSWORD_NEW_PREVIOUSLY_USED: - case AS400SecurityException.PASSWORD_NEW_NO_NUMERIC: - case AS400SecurityException.PASSWORD_NEW_NO_ALPHABETIC: - case AS400SecurityException.PASSWORD_NEW_DISALLOWED: - case AS400SecurityException.PASSWORD_NEW_USERID: - case AS400SecurityException.PASSWORD_NEW_SAME_POSITION: - case AS400SecurityException.PASSWORD_NEW_CHARACTER_NOT_VALID: - case AS400SecurityException.PASSWORD_NEW_VALIDATION_PROGRAM: - - if (changingPassword_) - { - displayMessage(exc.getMessage(), ResourceBundleLoader.getText("DLG_CHANGE_PASSWORD_TITLE")); - if (!handlePasswordChange(system)) throw exc; - } - else // not changing password - { // Give user another chance on the sign-on dialog. - displayMessage(exc.getMessage(), ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); - if (!handleSignon(system, true, false)) throw exc; - } - break; + if (DEBUG) System.out.println("ToolboxSignonHandler.passwordExpired()"); - case AS400SecurityException.PASSWORD_EXPIRED: + AS400 system = (AS400)event.getSource(); + if (!system.isGuiAvailable()) return noGuiAvailable(); - // See if user wants to change password. - boolean response = displayMessage(ResourceBundleLoader.getText("EXC_PASSWORD_EXPIRED") + "\n" + ResourceBundleLoader.getText("DLG_CHANGE_PASSWORD_PROMPT"), ResourceBundleLoader.getText("DLG_SIGNON_TITLE"), true); - if (response) // User wants to change password. - { - if (!handlePasswordChange(system)) throw exc; - } - else // User canceled the password change. - { // Fail the sign-on. - throw exc; - } - break; + // See if user wants to change password, if so, display change password panel. + boolean response = displayMessage(ResourceBundleLoader.getText("EXC_PASSWORD_EXPIRED") + "\n" + ResourceBundleLoader.getText("DLG_CHANGE_PASSWORD_PROMPT"), + ResourceBundleLoader.getText("DLG_SIGNON_TITLE"), true); + if (response) + return handlePasswordChange(system); - default: // None of the above. Just display the error text to the user and throw the exception. + // User canceled the password change. + return false; + } - String title; - if (changingPassword_) - { - title = ResourceBundleLoader.getText("DLG_CHANGE_PASSWORD_TITLE"); - } - else - { - title = ResourceBundleLoader.getText("DLG_SIGNON_TITLE"); - } - displayMessage(exc.getMessage(), title); - throw exc; + /** + * Displays a message indicating that the password is incorrect, and redisplays + * the sign-on dialog. + * + * @param event The sign-on event. + * @return true if user clicks OK, false if user clicks Cancel. + **/ + @Override + public boolean passwordIncorrect(SignonEvent event) + { + if (DEBUG) System.out.println("ToolboxSignonHandler.passwordIncorrect()"); + + AS400 system = (AS400)event.getSource(); + if (!system.isGuiAvailable()) return noGuiAvailable(); + + displayMessage(ResourceBundleLoader.getText("EXC_PASSWORD_INCORRECT"), + ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); + return handleSignon(system, true, false); } - } + /** + * Displays a message indicating that the password length is incorrect, and + * redisplays the sign-on dialog. + * + * @param event The sign-on event. + * @return true if user clicks OK, false if user clicks Cancel. + **/ + @Override + public boolean passwordLengthIncorrect(SignonEvent event) + { + if (DEBUG) System.out.println("ToolboxSignonHandler.passwordLengthIncorrect()"); - // Solicits password-change information from the user. Validates the information, and if valid, calls AS400.changePassword(). - private boolean handlePasswordChange(AS400 system) - { - ChangePasswordDialog cpd = new ChangePasswordDialog(new Frame(), ResourceBundleLoader.getText("DLG_CHANGE_PASSWORD_TITLE")); - boolean changedPassword = false; - boolean done = false; + AS400 system = (AS400)event.getSource(); + if (!system.isGuiAvailable()) return noGuiAvailable(); + displayMessage(ResourceBundleLoader.getText("EXC_PASSWORD_LENGTH_NOT_VALID"), + ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); + return handleSignon(system, true, false); + } - do + /** + * Displays a message indicating that the password was not specified, and + * redisplays the sign-on dialog. + * + * @param event The sign-on event. + * @return true if user clicks OK, false if user clicks Cancel. + **/ + @Override + public boolean passwordMissing(SignonEvent event) { - if (!cpd.prompt(system.getSystemName(), system.getUserId())) // user canceled - { - changingPassword_ = false; - break; - } - String oldPassword = cpd.getOldPassword(); - String newPassword = cpd.getNewPassword(); - String confirmPassword = cpd.getConfirmPassword(); - if (PASSWORD_TRACE) - { - Trace.log(Trace.DIAGNOSTIC, "Old password: '" + oldPassword + "'"); - Trace.log(Trace.DIAGNOSTIC, "New password: '" + newPassword + "'"); - Trace.log(Trace.DIAGNOSTIC, "Confirm password: '" + confirmPassword + "'"); - } - if (validatePasswordInfo(oldPassword, newPassword, confirmPassword)) - { - changingPassword_ = true; - try { - system.changePassword(oldPassword, newPassword); - } - catch (AS400SecurityException e) { - displayMessage(e.getMessage(), ResourceBundleLoader.getText("DLG_CHANGE_PASSWORD_TITLE")); - return handlePasswordChange(system); - } - catch (IOException e) { - displayMessage(e.getMessage(), ResourceBundleLoader.getText("DLG_CHANGE_PASSWORD_TITLE")); - return handlePasswordChange(system); - } - changingPassword_ = false; - changedPassword = true; - done = true; - } - - } while (!done); - - return changedPassword; - } - - - /** - Gathers any missing sign-on information, and calls the relevant setters in the system object. - If GUI is available, displays an interactive sign-on dialog to the user, with fields for systemName, userID, and password, along with "OK" and "CANCEL" buttons. - Otherwise, simply returns true. - @param event The sign-on event. - @param forceUpdate true indicates that the sign-on information is known to be incomplete or incorrect. false indicates that the information may be correct. - @param enableSystemNameField Indicates whether the "system name" field should be enabled for input. - @return true if sign-on should proceed, false if sign-on should not proceed. - **/ - private boolean handleSignon(AS400 system, boolean forceUpdate, boolean enableSystemNameField) - { - if (DEBUG) System.out.println("ToolboxSignonHandler.handleSignon("+forceUpdate+"," + enableSystemNameField+")"); - - if (!forceUpdate && - system.getSystemName().length() != 0 && - system.getUserId().length() != 0) - { - return true; // assume all the needed info is there + if (DEBUG) System.out.println("ToolboxSignonHandler.passwordMissing()"); + + AS400 system = (AS400)event.getSource(); + if (!system.isGuiAvailable()) return noGuiAvailable(); + displayMessage(ResourceBundleLoader.getText("DLG_MISSING_PASSWORD"), + ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); + return connectionInitiated(event, true); } - if (system.isGuiAvailable()) + /** + * Displays a message indicating that the system name was not specified, and + * redisplays the sign-on dialog. + * + * @param event The sign-on event. + * @return true if user clicks OK, false if user clicks Cancel. + **/ + @Override + public boolean systemNameMissing(SignonEvent event) { - if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Signing-on with prompting turned on."); - boolean done = false; - do - { - PasswordDialog pd = setupPasswordDialog(system); - if (enableSystemNameField) pd.enableSystemNameField(); - - if (!pd.prompt()) { // user canceled - return false; - } + if (DEBUG) System.out.println("ToolboxSignonHandler.systemNameMissing()"); - // Note: The PasswordDialog getters never return null. - String systemName = pd.getSystemName().trim(); - String userId = pd.getUserId().trim().toUpperCase(); - String password = pd.getPassword(); + AS400 system = (AS400)event.getSource(); + if (!system.isGuiAvailable()) return noGuiAvailable(); + displayMessage(ResourceBundleLoader.getText("DLG_MISSING_USERID"), // generic MRI + ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); + return handleSignon(system, true, true); + } - if (validateInfo(systemName, userId, password, system)) - { - try - { - systemName_ = systemName; - system.setSystemName(systemName_); - if (userId.length() != 0) { - userId_ = userId; - system.setUserId(userId_); - } - if (password.length() != 0) system.setPassword(password); - // Check to see if we should set the default user. - // Design note: There's a slight usability exposure here, in the event that an erroneous userID is specified. Then that userID gets set as the default user. To reset it, the app must first call AS400.removeDefaultUser(). - if (pd.getDefaultState() && userId_.length() != 0) - { - if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Setting default user from dialog..."); - // Set the default user. - if (!AS400.setDefaultUser(systemName_, userId_)) - { - if (Trace.traceOn_) Trace.log(Trace.WARNING, "Failed to set default user."); - if (system.isGuiAvailable()) - { - displayMessage(ResourceBundleLoader.getText("DLG_DEFAULT_USER_EXISTS") + "\n\n" + ResourceBundleLoader.getText("DLG_SET_DEFAULT_USER_FAILED"), - ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); - } - } - } + // Design Note: In order to preserve historical default behavior, this class does not implement the systemNameUnknown() method. + // If an unknown system name is specified, an UnknownHostException will be thrown. - // Also see if the AS400 should use the cached password. - if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Setting password cache entry from dialog..."); - system.setUsePasswordCache(pd.getPasswordCacheState()); - done = true; // if we got this far, we're good to go - } - catch (PropertyVetoException e) { - displayMessage(e.getMessage(), ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); - return handleSignon(system, forceUpdate, enableSystemNameField); - } - } + /** + * Displays a message indicating that the user profile will be disabled if next + * sign-on attempt is incorrect, and redisplays the sign-on dialog. + * + * @param event The sign-on event. + * @return true if user clicks OK, false if user clicks Cancel. + **/ + @Override + public boolean userIdAboutToBeDisabled(SignonEvent event) + { + if (DEBUG) System.out.println("ToolboxSignonHandler.userIdAboutToBeDisabled()"); - } while (!done); + AS400 system = (AS400)event.getSource(); + if (!system.isGuiAvailable()) return noGuiAvailable(); + displayMessage(ResourceBundleLoader.getText("EXC_PASSWORD_INCORRECT_USERID_DISABLE"), + ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); + return handleSignon(system, true, false); } - else // no GUI available + + /** + * Displays a message warning that the system object already has a default user + * assigned. + * + * @param event The sign-on event. + * @param defaultUser The current default user. + * @return true + **/ + @Override + public boolean userIdDefaultAlreadyAssigned(SignonEvent event, String defaultUser) { - // Just return true. Let the caller validate it. - // If anything necessary is missing, they will call our handleEvent() method. - if (Trace.traceOn_) Trace.log(Trace.INFORMATION, "No GUI is available to sign-on handler."); + if (DEBUG) System.out.println("ToolboxSignonHandler.userIdDefaultAlreadyAssigned()"); + + // Put up an informational message, and proceed with sign-on. + displayMessage(ResourceBundleLoader.getText("DLG_DEFAULT_USER_EXISTS"), + ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); + displayMessage(ResourceBundleLoader.getText("DLG_SET_DEFAULT_USER_FAILED"), + ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); + return true; } - return true; - } - - - // Complains about missing GUI, and returns false. - private boolean noGuiAvailable() - { - Trace.log(Trace.ERROR, "The internal Toolbox sign-on handler requires a GUI in order to gather new information."); - return false; - } + /** + * Displays a message indicating that the user profile is disabled, and + * redisplays the sign-on dialog. + * + * @param event The sign-on event. + * @return true if user clicks OK, false if user clicks Cancel. + **/ + @Override + public boolean userIdDisabled(SignonEvent event) + { + if (DEBUG) System.out.println("ToolboxSignonHandler.userIdDisabled()"); + AS400 system = (AS400)event.getSource(); + if (!system.isGuiAvailable()) return noGuiAvailable(); + displayMessage(ResourceBundleLoader.getText("EXC_USERID_DISABLE"), + ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); + return handleSignon(system, true, false); + } - // Sets up a password dialog, to solicit system name, user ID, and password. - private PasswordDialog setupPasswordDialog(AS400 system) - { - PasswordDialog pd = new PasswordDialog(new Frame(), ResourceBundleLoader.getText("DLG_SIGNON_TITLE"), system.isShowCheckboxes()); - // If system name is not set. - String systemName = system.getSystemName(); - if (systemName.length() == 0) systemName = systemName_; - if (systemName.length() == 0) + /** + * Displays a message indicating that the user ID length is incorrect, and + * redisplays the sign-on dialog. + * + * @param event The sign-on event. + * @return true if user clicks OK, false if user clicks Cancel. + **/ + @Override + public boolean userIdLengthIncorrect(SignonEvent event) { - // Enable default user checkbox. - pd.enableDefaultUserCheckbox(); - // But uncheck it. - pd.setDefaultUserState(false); + if (DEBUG) System.out.println("ToolboxSignonHandler.userIdLengthIncorrect()"); + + AS400 system = (AS400)event.getSource(); + if (!system.isGuiAvailable()) return noGuiAvailable(); + displayMessage(ResourceBundleLoader.getText("EXC_USERID_LENGTH_NOT_VALID"), + ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); + return handleSignon(system, true, false); } - else + + /** + * Displays a message indicating that the user name was not specified, and + * redisplays the sign-on dialog. + * + * @param event The sign-on event. + * @return true if user clicks OK, false if user clicks Cancel. + **/ + @Override + public boolean userIdMissing(SignonEvent event) { - // Put system name in dialog. - pd.setSystemName(systemName); - systemName_ = systemName; - // Do we already have a default user for this system - if (AS400.getDefaultUser(systemName) == null) - { // No default user yet. - // Enable the check box. - pd.enableDefaultUserCheckbox(); - // And check it. - pd.setDefaultUserState(true); - } - else - { - // Disable the check box. There's already a default user for this system. - pd.disableDefaultUserCheckbox(); - } + if (DEBUG) System.out.println("ToolboxSignonHandler.userIdMissing()"); + + AS400 system = (AS400)event.getSource(); + if (!system.isGuiAvailable()) return noGuiAvailable(); + displayMessage(ResourceBundleLoader.getText("DLG_MISSING_USERID"), + ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); + return handleSignon(system, true, false); } - // Check the use cache checkbox. - pd.setPasswordCacheState(system.isUsePasswordCache()); - // If user ID set, put it in dialog. - String userId = system.getUserId(); - if (userId.length() == 0) userId = userId_; - if (userId.length() == 0 && systemName.length() != 0) { - String defaultUser = AS400.getDefaultUser(systemName); - if (defaultUser != null) userId = defaultUser; + + /** + * Displays a message indicating that the specified user ID is unknown, and + * redisplays the sign-on dialog. + * + * @param event The sign-on event. + * @return true if user clicks OK, false if user clicks Cancel. + **/ + @Override + public boolean userIdUnknown(SignonEvent event) + { + if (DEBUG) System.out.println("ToolboxSignonHandler.userIdUnknown()"); + + AS400 system = (AS400)event.getSource(); + if (!system.isGuiAvailable()) return noGuiAvailable(); + displayMessage(ResourceBundleLoader.getText("EXC_USERID_UNKNOWN"), + ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); + return handleSignon(system, true, false); } - if (userId.length() != 0) { - pd.setUserId(userId); - userId_ = userId; + + // + // + // Private utility methods. + // + // + + /** + * Displays an informational dialog to the user. + * + * @param message The message text to display. + * @param dialogTitle The title for the dialog. + **/ + private void displayMessage(String message, String dialogTitle) { + displayMessage(message, dialogTitle, false); } - return pd; - } - - - // Checks lengths of systemName, userID, and password. - private boolean validateInfo(String systemName, String userId, String password, AS400 system) - { - // Assume args are already validated as non-null. - boolean valid = true; - if (systemName.length() == 0 || - (!system.isUseDefaultUser() && userId.length() == 0) || - (!system.isUsePasswordCache() && password.length() == 0)) + + /** + * Displays an informational dialog to the user. + * + * @param message The message text to display. + * @param dialogTitle The title for the dialog. + * @param getResponse Whether to get response from user. + * @return The response from the user. true if user indicated approval, false + * otherwise. + **/ + private boolean displayMessage(String message, String dialogTitle, boolean getResponse) { - // A field is not filled in. - displayMessage(ResourceBundleLoader.getText("DLG_MISSING_PASSWORD"), ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); - valid = false; + MessageDialog md = new MessageDialog(new Frame(), message, dialogTitle, getResponse); + return md.display(); } - else if (password.length() > 128) + + /** + * Handles an exception that was thrown during a sign-on attempt. If the handler + * cannot deal with the exception, the handler rethrows exc. + * + * @param system The system. + * @param exc The exception. + * @exception AS400SecurityException If the handler cannot handle the exception. + **/ + private void handleException(AS400 system, AS400SecurityException exc) throws AS400SecurityException { - Trace.log(Trace.ERROR, "Length of password is greater than 128 characters: " + password.length()); - displayMessage(ResourceBundleLoader.getText("EXC_PASSWORD_LENGTH_NOT_VALID"), ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); - valid = false; - } + switch (exc.getReturnCode()) + { + case AS400SecurityException.USERID_LENGTH_NOT_VALID: + case AS400SecurityException.PASSWORD_LENGTH_NOT_VALID: + case AS400SecurityException.USERID_DISABLE: + case AS400SecurityException.PASSWORD_INCORRECT: + case AS400SecurityException.PASSWORD_INCORRECT_USERID_DISABLE: + case AS400SecurityException.SIGNON_REQUEST_NOT_VALID: + case AS400SecurityException.USERID_UNKNOWN: + case AS400SecurityException.SIGNON_CHAR_NOT_VALID: + + case AS400SecurityException.PASSWORD_CHANGE_REQUEST_NOT_VALID: + case AS400SecurityException.PASSWORD_OLD_NOT_VALID: + case AS400SecurityException.PASSWORD_NEW_NOT_VALID: + case AS400SecurityException.PASSWORD_NEW_TOO_LONG: + case AS400SecurityException.PASSWORD_NEW_TOO_SHORT: + case AS400SecurityException.PASSWORD_NEW_REPEAT_CHARACTER: + case AS400SecurityException.PASSWORD_NEW_ADJACENT_DIGITS: + case AS400SecurityException.PASSWORD_NEW_CONSECUTIVE_REPEAT_CHARACTER: + case AS400SecurityException.PASSWORD_NEW_PREVIOUSLY_USED: + case AS400SecurityException.PASSWORD_NEW_NO_NUMERIC: + case AS400SecurityException.PASSWORD_NEW_NO_ALPHABETIC: + case AS400SecurityException.PASSWORD_NEW_DISALLOWED: + case AS400SecurityException.PASSWORD_NEW_USERID: + case AS400SecurityException.PASSWORD_NEW_SAME_POSITION: + case AS400SecurityException.PASSWORD_NEW_CHARACTER_NOT_VALID: + case AS400SecurityException.PASSWORD_NEW_VALIDATION_PROGRAM: + + if (changingPassword_) + { + displayMessage(exc.getMessage(), ResourceBundleLoader.getText("DLG_CHANGE_PASSWORD_TITLE")); + if (!handlePasswordChange(system)) throw exc; + } + else + { + // not changing password, Give user another chance on the sign-on dialog. + displayMessage(exc.getMessage(), ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); + if (!handleSignon(system, true, false)) throw exc; + } + + break; - return valid; - } + case AS400SecurityException.PASSWORD_EXPIRED: + + // See if user wants to change password. + boolean response = displayMessage(ResourceBundleLoader.getText("EXC_PASSWORD_EXPIRED") + "\n" + ResourceBundleLoader.getText("DLG_CHANGE_PASSWORD_PROMPT"), + ResourceBundleLoader.getText("DLG_SIGNON_TITLE"), true); + if (response) + { + // User wants to change password. + if (!handlePasswordChange(system)) throw exc; + } + else + { + // User canceled the password change. Fail the sign-on. + throw exc; + } + + break; + + default: + // None of the above. Just display the error text to the user and throw the exception. + String title = (changingPassword_) ? ResourceBundleLoader.getText("DLG_CHANGE_PASSWORD_TITLE") : ResourceBundleLoader.getText("DLG_SIGNON_TITLE"); + displayMessage(exc.getMessage(), title); + throw exc; + } + } - // Checks lengths of old/new passwords, and verifies that they match. - private boolean validatePasswordInfo(String oldPassword, String newPassword, String confirmPassword) - { - if (oldPassword.length() == 0 || newPassword.length() == 0 || confirmPassword.length() == 0) + // Solicits password-change information from the user. Validates the information, and if valid, calls AS400.changePassword(). + private boolean handlePasswordChange(AS400 system) { - // A field is not filled in. - displayMessage(ResourceBundleLoader.getText("DLG_MISSING_PASSWORD"), ResourceBundleLoader.getText("DLG_CHANGE_PASSWORD_TITLE")); - return false; + ChangePasswordDialog cpd = new ChangePasswordDialog(new Frame(), ResourceBundleLoader.getText("DLG_CHANGE_PASSWORD_TITLE"), showFactor(system)); + boolean changedPassword = false; + boolean done = false; + + do + { + if (!cpd.prompt(system.getSystemName(), system.getUserId())) // user canceled + { + changingPassword_ = false; + break; + } + + String oldPassword = cpd.getOldPassword(); + String newPassword = cpd.getNewPassword(); + String confirmPassword = cpd.getConfirmPassword(); + String additionalFactor = cpd.getAdditionalFactor(); + + if (PASSWORD_TRACE) + { + Trace.log(Trace.DIAGNOSTIC, "Old password: '" + oldPassword + "'"); + Trace.log(Trace.DIAGNOSTIC, "New password: '" + newPassword + "'"); + Trace.log(Trace.DIAGNOSTIC, "Confirm password: '" + confirmPassword + "'"); + } + + if (validatePasswordInfo(oldPassword, newPassword, confirmPassword)) + { + changingPassword_ = true; + + try { + system.changePassword(oldPassword.toCharArray(), newPassword.toCharArray(), additionalFactor.toCharArray()); + } + catch (AS400SecurityException|IOException e) { + displayMessage(e.getMessage(), ResourceBundleLoader.getText("DLG_CHANGE_PASSWORD_TITLE")); + return handlePasswordChange(system); + } + + changingPassword_ = false; + changedPassword = true; + done = true; + } + } + while (!done); + + return changedPassword; } - if (!newPassword.equals(confirmPassword)) + + + /** + * Gathers any missing sign-on information, and calls the relevant setters in + * the system object. If GUI is available, displays an interactive sign-on + * dialog to the user, with fields for systemName, userID, and password, along + * with "OK" and "CANCEL" buttons. Otherwise, simply returns true. + * + * @param event The sign-on event. + * @param forceUpdate true indicates that the sign-on + * information is known to be incomplete or + * incorrect. false indicates that the + * information may be correct. + * @param enableSystemNameField Indicates whether the "system name" field should + * be enabled for input. + * @return true if sign-on should proceed, false if sign-on should not proceed. + **/ + private boolean handleSignon(AS400 system, boolean forceUpdate, boolean enableSystemNameField) { - // New and confirm are not the same. - displayMessage(ResourceBundleLoader.getText("EXC_PASSWORD_NOT_MATCH"), ResourceBundleLoader.getText("DLG_CHANGE_PASSWORD_TITLE")); - return false; + if (DEBUG) System.out.println("ToolboxSignonHandler.handleSignon("+forceUpdate+"," + enableSystemNameField+")"); + + if (!forceUpdate && system.getSystemName().length() != 0 && system.getUserId().length() != 0) + return true; // assume all the needed info is there + + if (system.isGuiAvailable()) + { + if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Signing-on with prompting turned on."); + + boolean done = false; + do + { + PasswordDialog pd = setupPasswordDialog(system); + if (enableSystemNameField) pd.enableSystemNameField(); + + // user canceled? + if (!pd.prompt()) + return false; + + // Note: The PasswordDialog getters never return null. + String systemName = pd.getSystemName().trim(); + String userId = pd.getUserId().trim().toUpperCase(); + String password = pd.getPassword(); + String factor = pd.getAdditionalFactor(); + + if (validateInfo(systemName, userId, password, system)) + { + try + { + systemName_ = systemName; + system.setSystemName(systemName_); + if (userId.length() != 0) { + userId_ = userId; + system.setUserId(userId_); + } + if (password.length() != 0) system.setPassword(password.toCharArray()); + system.setAdditionalAuthenticationFactor(factor.toCharArray()); + + // Check to see if we should set the default user. + // Design note: There's a slight usability exposure here, in the event that an + // erroneous userID is specified. Then that userID gets set as the default user. + // To reset it, the app must first call AS400.removeDefaultUser(). + if (pd.getDefaultState() && userId_.length() != 0) + { + if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Setting default user from dialog..."); + + // Set the default user. + if (!AS400.setDefaultUser(systemName_, userId_)) + { + if (Trace.traceOn_) Trace.log(Trace.WARNING, "Failed to set default user."); + if (system.isGuiAvailable()) + { + displayMessage(ResourceBundleLoader.getText("DLG_DEFAULT_USER_EXISTS") + "\n\n" + ResourceBundleLoader.getText("DLG_SET_DEFAULT_USER_FAILED"), + ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); + } + } + } + + // Also see if the AS400 should use the cached password. + if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Setting password cache entry from dialog..."); + system.setUsePasswordCache(pd.getPasswordCacheState()); + + done = true; // if we got this far, we're good to go + } + catch (PropertyVetoException e) { + displayMessage(e.getMessage(), ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); + return handleSignon(system, forceUpdate, enableSystemNameField); + } + } + + } + while (!done); + } + else // no GUI available + { + // Just return true. Let the caller validate it. + // If anything necessary is missing, they will call our handleEvent() method. + if (Trace.traceOn_) Trace.log(Trace.INFORMATION, "No GUI is available to sign-on handler."); + } + + return true; } - if (oldPassword.length() > 128) + + // Complains about missing GUI, and returns false. + private boolean noGuiAvailable() { - Trace.log(Trace.ERROR, "Length of old password is greater than 128 characters: " + oldPassword.length()); - displayMessage(ResourceBundleLoader.getText("EXC_PASSWORD_LENGTH_NOT_VALID"), ResourceBundleLoader.getText("DLG_CHANGE_PASSWORD_TITLE")); - return false; + Trace.log(Trace.ERROR, "The internal Toolbox sign-on handler requires a GUI in order to gather new information."); + return false; } - if (newPassword.length() > 128) + + // Sets up a password dialog, to solicit system name, user ID, and password. + private PasswordDialog setupPasswordDialog(AS400 system) + { + PasswordDialog pd = new PasswordDialog(new Frame(), ResourceBundleLoader.getText("DLG_SIGNON_TITLE"), system.isShowCheckboxes(), showFactor(system)); + + // If system name is not set. + String systemName = system.getSystemName(); + if (systemName.length() == 0) systemName = systemName_; + + if (systemName.length() == 0) + { + // Enable default user checkbox. + pd.enableDefaultUserCheckbox(); + // But uncheck it. + pd.setDefaultUserState(false); + } + else + { + // Put system name in dialog. + pd.setSystemName(systemName); + systemName_ = systemName; + + // Do we already have a default user for this system + if (AS400.getDefaultUser(systemName) == null) + { + // No default user yet. + // Enable the check box. + pd.enableDefaultUserCheckbox(); + // And check it. + pd.setDefaultUserState(true); + } + else + { + // Disable the check box. There's already a default user for this system. + pd.disableDefaultUserCheckbox(); + } + } + + // Check the use cache checkbox. + pd.setPasswordCacheState(system.isUsePasswordCache()); + + // If user ID set, put it in dialog. + String userId = system.getUserId(); + if (userId.length() == 0) userId = userId_; + if (userId.length() == 0 && systemName.length() != 0) + { + String defaultUser = AS400.getDefaultUser(systemName); + if (defaultUser != null) userId = defaultUser; + } + + if (userId.length() != 0) { + pd.setUserId(userId); + userId_ = userId; + } + + return pd; + } + + // Checks lengths of systemName, userID, and password. + private boolean validateInfo(String systemName, String userId, String password, AS400 system) { - Trace.log(Trace.ERROR, "Length of new password is greater than 128 characters: " + newPassword.length()); - displayMessage(ResourceBundleLoader.getText("EXC_PASSWORD_NEW_NOT_VALID"), ResourceBundleLoader.getText("DLG_CHANGE_PASSWORD_TITLE")); - return false; + // Assume args are already validated as non-null. + boolean valid = true; + if (systemName.length() == 0 || + (!system.isUseDefaultUser() && userId.length() == 0) || + (!system.isUsePasswordCache() && password.length() == 0)) + { + // A field is not filled in. + displayMessage(ResourceBundleLoader.getText("DLG_MISSING_PASSWORD"), ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); + valid = false; + } + else if (password.length() > 128) + { + Trace.log(Trace.ERROR, "Length of password is greater than 128 characters: " + password.length()); + displayMessage(ResourceBundleLoader.getText("EXC_PASSWORD_LENGTH_NOT_VALID"), ResourceBundleLoader.getText("DLG_SIGNON_TITLE")); + valid = false; + } + + return valid; } - return true; - } + // Checks lengths of old/new passwords, and verifies that they match. + private boolean validatePasswordInfo(String oldPassword, String newPassword, String confirmPassword) + { + if (oldPassword.length() == 0 || newPassword.length() == 0 || confirmPassword.length() == 0) + { + // A field is not filled in. + displayMessage(ResourceBundleLoader.getText("DLG_MISSING_PASSWORD"), ResourceBundleLoader.getText("DLG_CHANGE_PASSWORD_TITLE")); + return false; + } + + if (!newPassword.equals(confirmPassword)) + { + // New and confirm are not the same. + displayMessage(ResourceBundleLoader.getText("EXC_PASSWORD_NOT_MATCH"), ResourceBundleLoader.getText("DLG_CHANGE_PASSWORD_TITLE")); + return false; + } + + if (oldPassword.length() > 128) + { + Trace.log(Trace.ERROR, "Length of old password is greater than 128 characters: " + oldPassword.length()); + displayMessage(ResourceBundleLoader.getText("EXC_PASSWORD_LENGTH_NOT_VALID"), ResourceBundleLoader.getText("DLG_CHANGE_PASSWORD_TITLE")); + return false; + } + + if (newPassword.length() > 128) + { + Trace.log(Trace.ERROR, "Length of new password is greater than 128 characters: " + newPassword.length()); + displayMessage(ResourceBundleLoader.getText("EXC_PASSWORD_NEW_NOT_VALID"), ResourceBundleLoader.getText("DLG_CHANGE_PASSWORD_TITLE")); + return false; + } + return true; + } + + private boolean showFactor(AS400 system) + { + try { + return AS400.isAdditionalAuthenticationFactorAccepted(system.getSystemName(), system.isSecure()); + } catch (Exception e) { + // Ignore and just show it + } + + return true; + } } diff --git a/src/main/java/com/ibm/as400/security/auth/AS400BasicAuthenticationCredential.java b/src/main/java/com/ibm/as400/security/auth/AS400BasicAuthenticationCredential.java index c31a5d46d..b926f7cf8 100644 --- a/src/main/java/com/ibm/as400/security/auth/AS400BasicAuthenticationCredential.java +++ b/src/main/java/com/ibm/as400/security/auth/AS400BasicAuthenticationCredential.java @@ -13,104 +13,89 @@ // /////////////////////////////////////////////////////////////////////////////// /** - * The AS400BasicAuthenticationCredential interface defines IBM i - * credentials that can be exploited by authentication services - * that rely on basic user and password authentication. + * The AS400BasicAuthenticationCredential interface defines IBM i credentials + * that can be exploited by authentication services that rely on basic user and + * password authentication. * */ -public interface AS400BasicAuthenticationCredential { +public interface AS400BasicAuthenticationCredential +{ -/** - * Returns text that can be displayed to prompt for the basic user - * and password information used to initialize the credential. - * - * @return - * An array of two Strings. The first string is the text to - * prompt for the user name; the second is the text to - * prompt for the password. - * - */ -public String[] basicAuthenticationPrompt(); -/** - * Initializes and validates a credential for the local IBM i system. - * - * @param principal - * The principal identifying the authenticated user. - * - * @param password - * The password for the authenticated user. - * - * @param isPrivate - * Indicates whether the credential is considered private. - * - * @param isReusable - * true if the credential can be used to swap - * thread identity multiple times; - * otherwise false. - * - * @param isRenewable - * true if the validity period of the credential - * can be programmatically updated or extended; - * otherwise false. - * - * @param timeoutInterval - * The number of seconds to expiration when the credential - * is initially created; ignored if the credential - * does not expire based on time. - * - * @exception Exception - * If an exception occurs. - * - * @deprecated Use initialize(AS400BasicAuthenticationPrincipal principal, char[] password, - boolean isPrivate, boolean isReusable, boolean isRenewable, - int timeoutInterval) instead - */ -public void initialize(AS400BasicAuthenticationPrincipal principal, String password, - boolean isPrivate, boolean isReusable, boolean isRenewable, int timeoutInterval) throws Exception; + /** + * Returns text that can be displayed to prompt for the basic user and password + * information used to initialize the credential. + * + * @return An array of two Strings. The first string is the text to prompt for + * the user name; the second is the text to prompt for the password. + * + */ + public String[] basicAuthenticationPrompt(); -/** - * Initializes and validates a credential for the local IBM i system. - * - * @param principal - * The principal identifying the authenticated user. - * - * @param password - * The password for the authenticated user. - * - * @param isPrivate - * Indicates whether the credential is considered private. - * - * @param isReusable - * true if the credential can be used to swap - * thread identity multiple times; - * otherwise false. - * - * @param isRenewable - * true if the validity period of the credential - * can be programmatically updated or extended; - * otherwise false. - * - * @param timeoutInterval - * The number of seconds to expiration when the credential - * is initially created; ignored if the credential - * does not expire based on time. - * - * @exception Exception - * If an exception occurs. - * - */ -public void initialize(AS400BasicAuthenticationPrincipal principal, char[] password, - boolean isPrivate, boolean isReusable, boolean isRenewable, int timeoutInterval) throws Exception; + /** + * Initializes and validates a credential for the local IBM i system. + * + * @param principal The principal identifying the authenticated user. + * + * @param password The password for the authenticated user. + * + * @param isPrivate Indicates whether the credential is considered + * private. + * + * @param isReusable true if the credential can be used to swap thread + * identity multiple times; otherwise false. + * + * @param isRenewable true if the validity period of the credential can be + * programmatically updated or extended; otherwise false. + * + * @param timeoutInterval The number of seconds to expiration when the + * credential is initially created; ignored if the + * credential does not expire based on time. + * + * @exception Exception If an exception occurs. + * + * @deprecated Use + * {{@link #initialize(AS400BasicAuthenticationPrincipal, char[], boolean, boolean, boolean, int)} + * instead + */ + @Deprecated + public void initialize(AS400BasicAuthenticationPrincipal principal, String password, boolean isPrivate, + boolean isReusable, boolean isRenewable, int timeoutInterval) throws Exception; -/** - * Indicates whether the credential is considered private. - * - *

This value can be referenced by authentication services - * as an indication of when to check permissions or otherwise - * protect access to sensitive credentials. - * - * @return - * true if private; false if public. - */ -public boolean isPrivate(); + /** + * Initializes and validates a credential for the local IBM i system. + * + * @param principal The principal identifying the authenticated user. + * + * @param password The password for the authenticated user. + * + * @param isPrivate Indicates whether the credential is considered + * private. + * + * @param isReusable true if the credential can be used to swap thread + * identity multiple times; otherwise false. + * + * @param isRenewable true if the validity period of the credential can be + * programmatically updated or extended; otherwise false. + * + * @param timeoutInterval The number of seconds to expiration when the + * credential is initially created; ignored if the + * credential does not expire based on time. + * + * @exception Exception If an exception occurs. + * + */ + public void initialize(AS400BasicAuthenticationPrincipal principal, char[] password, boolean isPrivate, + boolean isReusable, boolean isRenewable, int timeoutInterval) throws Exception; + + /** + * Indicates whether the credential is considered private. + * + *

+ * This value can be referenced by authentication services as an indication of + * when to check permissions or otherwise protect access to sensitive + * credentials. + * + * @return true if private; false if public. + */ + public boolean isPrivate(); } diff --git a/src/main/java/com/ibm/as400/security/auth/ProfileTokenCredential.java b/src/main/java/com/ibm/as400/security/auth/ProfileTokenCredential.java index a305c75b1..dcabc9140 100644 --- a/src/main/java/com/ibm/as400/security/auth/ProfileTokenCredential.java +++ b/src/main/java/com/ibm/as400/security/auth/ProfileTokenCredential.java @@ -194,7 +194,8 @@ public final class ProfileTokenCredential extends AS400Credential implements AS4 private byte[] token_ = null; // encoded token private int type_ = TYPE_SINGLE_USE; private int timeoutInterval_ = 3600; - + + private boolean noRefresh_ = false; private final static int MAX_USERPROFILE_LENGTH = 10; @@ -259,10 +260,6 @@ public ProfileTokenCredential() * 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 token attributes, such as the @@ -285,7 +282,7 @@ public ProfileTokenCredential() * @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) + public ProfileTokenCredential(AS400 system, byte[] token, int tokenType, int timeoutInterval) { this(); try { @@ -293,8 +290,7 @@ public ProfileTokenCredential(AS400 system, byte[] token, int tokenType, int tim setToken(token); setTokenType(tokenType); setTimeoutInterval(timeoutInterval); - } - catch (PropertyVetoException pve) { + } catch (PropertyVetoException pve) { AuthenticationSystem.handleUnexpectedException(pve); } } @@ -443,57 +439,17 @@ public int hashCode() return hash; } - /** - * Returns the name of the class providing an implementation for code delegated - * by the credential that performs native optimization when running on an IBM i - * system. - * - * @return The qualified class name for native optimizations. - */ @Override String implClassNameNative() { return "com.ibm.as400.access.ProfileTokenImplNative"; } - /** - * Returns the name of the class providing an implementation for code delegated - * by the credential when no native optimization is to be performed. - * - * @return The qualified class name. - */ @Override String implClassNameRemote() { return "com.ibm.as400.security.auth.ProfileTokenImplRemote"; } - /** - * Initializes and validates a credential for the local IBM i system. - * - * @param principal The principal identifying the authenticated user. If - * not an instance of AS400Principal, a corresponding - * UserProfilePrincipal is generated and assigned. - * - * @param password The password for the authenticated user. - * - * @param isPrivate Indicates whether the credential is considered - * private. - * - * @param isReusable true if the credential can be used to swap thread - * identity multiple times; otherwise false. - * - * @param isRenewable true if the validity period of the credential can be - * programmatically updated or extended; otherwise false. - * - * @param timeoutInterval The number of seconds to expiration when the - * credential is initially created; ignored if the - * credential does not expire based on time. - * - * @exception Exception If an exception occurs. - * - * @deprecated Use initialize(AS400BasicAuthenticationPrincipal principal, - * char[] password, boolean isPrivate, boolean isReusable, boolean - * isRenewable, int timeoutInterval) instead. - */ + @Deprecated @Override public void initialize(AS400BasicAuthenticationPrincipal principal, String password, boolean isPrivate, boolean isReusable, boolean isRenewable, int timeoutInterval) throws Exception @@ -507,93 +463,50 @@ public void initialize(AS400BasicAuthenticationPrincipal principal, String passw } } - /** - * Initializes and validates a credential for the local IBM i system. - * - * @param principal - * The principal identifying the authenticated user. - * If not an instance of AS400Principal, a corresponding - * UserProfilePrincipal is generated and assigned. - * - * @param password - * The password for the authenticated user. - * - * @param isPrivate - * Indicates whether the credential is considered private. - * - * @param isReusable - * true if the credential can be used to swap - * thread identity multiple times; - * otherwise false. - * - * @param isRenewable - * true if the validity period of the credential - * can be programmatically updated or extended; - * otherwise false. - * - * @param timeoutInterval - * The number of seconds to expiration when the credential - * is initially created; ignored if the credential - * does not expire based on time. - * - * @exception Exception - * If an exception occurs. - * - */ - public void initialize(AS400BasicAuthenticationPrincipal principal, - char[] password, boolean isPrivate, boolean isReusable, - boolean isRenewable, int timeoutInterval) - throws Exception { + @Override + public void initialize(AS400BasicAuthenticationPrincipal principal, char[] password, boolean isPrivate, + boolean isReusable, boolean isRenewable, int timeoutInterval) throws Exception + { if (Trace.isTraceOn()) + { Trace.log(Trace.INFORMATION, - new StringBuffer("Initializing credential >> " - ).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()); + new StringBuffer("Initializing credential >> ").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."); + 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); + 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 + 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); + 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. - */ @Override void invalidateProperties() { @@ -601,14 +514,6 @@ void 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 - */ @Override public boolean isRenewable() { return type_ == TYPE_MULTIPLE_USE_RENEWABLE; @@ -634,20 +539,6 @@ 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. - */ @Override public void refresh() throws AS400SecurityException { refresh(getTokenType(), getTimeoutInterval()); @@ -884,6 +775,7 @@ public synchronized void setToken(byte[] bytes) throws PropertyVetoException * initialized due to the current * state. */ + @Deprecated public void setToken(AS400Principal principal, String password) throws PropertyVetoException, AS400SecurityException { setToken(principal.getUserProfileName(), password); } @@ -938,6 +830,7 @@ public void setToken(AS400Principal principal, String password) throws PropertyV * state. * */ + @Deprecated public void setToken(String name, String password) throws PropertyVetoException, AS400SecurityException { // Validate state @@ -1111,8 +1004,7 @@ public void setToken(String name, int passwordSpecialValue) throws PropertyVetoE break; default: Trace.log(Trace.ERROR, "Special value for password is not valid"); - throw new ExtendedIllegalArgumentException("password", - ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); + throw new ExtendedIllegalArgumentException("password", ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); } // Instantiate a new impl but do not yet set as the default impl_ @@ -1163,6 +1055,7 @@ public void setToken(String name, int passwordSpecialValue) throws PropertyVetoE * @deprecated Use setTokenExtended(AS400Principal principal, char[] password) * instead */ + @Deprecated public void setTokenExtended(AS400Principal principal, String password) throws PropertyVetoException, AS400SecurityException { setTokenExtended(principal.getUserProfileName(), password); } @@ -1238,6 +1131,7 @@ public void setTokenExtended(AS400Principal principal, char[] password) throws P * * @deprecated Use setTokenExtended(String name, char[] password) instead. */ + @Deprecated public void setTokenExtended(String name, String password) throws PropertyVetoException, AS400SecurityException { char[] passwordChars = (password == null) ? null : password.toCharArray(); @@ -1307,12 +1201,8 @@ public void setTokenExtended(String name, char[] password) throws PropertyVetoEx ProfileTokenImpl impl = (ProfileTokenImpl)getImplPrimitive(); // Generate and set the token value - setToken( - impl.generateTokenExtended( - name, - password, - getTokenType(), - getTimeoutInterval())); + setToken(impl.generateTokenExtended(name, password, + getTokenType(), getTimeoutInterval())); // If successful, all defining attributes are now set. // Set the impl for subsequent references. @@ -1369,11 +1259,6 @@ public void setTokenType(int type) throws PropertyVetoException firePropertyChange("tokenType", old, typ); } - /** - * Returns a string representation of the object - * - * @return a string representation of the object. - */ @Override public String toString() { @@ -1381,47 +1266,16 @@ public String toString() .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 - */ @Override 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 - */ @Override 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. - * - */ @Override void validateProperties() { super.validateProperties(); diff --git a/src/main/java/com/ibm/as400/security/auth/ProfileTokenImplRemote.java b/src/main/java/com/ibm/as400/security/auth/ProfileTokenImplRemote.java index a19f9ebd9..cb41bfd66 100644 --- a/src/main/java/com/ibm/as400/security/auth/ProfileTokenImplRemote.java +++ b/src/main/java/com/ibm/as400/security/auth/ProfileTokenImplRemote.java @@ -20,83 +20,35 @@ * behavior delegated by a ProfileTokenCredential object. * */ -class ProfileTokenImplRemote extends AS400CredentialImplRemote - implements ProfileTokenImpl { - - /** - * Destroy or clear sensitive information maintained - * by the credential implementation. - * - *

Subsequent requests may result in a NullPointerException. - * - *

This class will also attempt to remove the associated - * profile token from the IBM i system. - * - * @exception DestroyFailedException - * If errors occur while destroying or clearing - * credential implementation data. - * - */ +class ProfileTokenImplRemote extends AS400CredentialImplRemote implements ProfileTokenImpl +{ + @Override public void destroy() throws DestroyFailedException { removeFromSystem(); super.destroy(); } - /** - * Generates and returns a new profile token based on - * the provided information. - * - * @deprecated As of V5R3, replaced - * by {@link #generateTokenExtended(String,String,int,int)}. - * - * @param uid - * The name of the user profile for which the token - * is to be generated. - * - * @param pwd - * The user profile password. Special values are not supported. - * - * @param type - * The type of token. - * Possible types are defined as fields on the - * ProfileTokenCredential class: - *

- *

- * - * @param timeoutInterval - * The number of seconds to expiration. - * - * @return - * The token bytes. - * - * @exception RetrieveFailedException - * If errors occur while generating the token. - * - */ - public byte[] generateToken(String uid, String pwd, int type, - int timeoutInterval) throws RetrieveFailedException { + @Deprecated + @Override + public byte[] generateToken(String uid, String pwd, int type, int timeoutInterval) throws RetrieveFailedException + { AS400 sys = getCredential().getSystem(); // Deprecated as of V5R3 try { - if ( sys.getVRM() >= 0x00050300 ) { - Trace.log(Trace.ERROR, - "setToken(String,String,in,int) deprecated." + - "Use setTokenExtended(String,String,int,int)."); - throw new ExtendedIllegalArgumentException("Method deprecated", - ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); + if ( sys.getVRM() >= 0x00050300 ) + { + Trace.log(Trace.ERROR, "setToken(String,String,in,int) deprecated. Use setTokenExtended(String,String,int,int)."); + throw new ExtendedIllegalArgumentException("Method deprecated", ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); } } catch (AS400SecurityException se) { throw new RetrieveFailedException(se.getReturnCode()); } catch (java.io.IOException ioe) { - AuthenticationSystem.handleUnexpectedException(ioe); } + AuthenticationSystem.handleUnexpectedException(ioe); + } // Use the AS400 object to obtain the token. // This will obtain the token by interacting with the IBM i @@ -111,55 +63,13 @@ public byte[] generateToken(String uid, String pwd, int type, catch (Exception e) { AuthenticationSystem.handleUnexpectedException(e); } + return tkn; } - //$A2 - /** - * Generates and returns a new profile token based on - * the provided information using a password special value. - *

- * This method should be used for generating a token using a - * password special value. - * - * @param uid - * The name of the user profile for which the token - * is to be generated. - *

- * - * @param pwdSpecialValue - * A password special value. - * Possible types are defined as fields on the - * ProfileTokenCredential class: - *

- *

- * - * @param type - * The type of token. - * Possible types are defined as fields on the ProfileTokenCredential class: - *

- *

- * - * @param timeoutInterval - * The number of seconds to expiration. - * - * @return - * The token bytes. - * - * @exception RetrieveFailedException - * If errors occur while generating the token. - * - */ - public byte[] generateToken(String uid, int pwdSpecialValue, int type, - int timeoutInterval) throws RetrieveFailedException { - + @Override + public byte[] generateToken(String uid, int pwdSpecialValue, int type, int timeoutInterval) throws RetrieveFailedException + { // Convert password special value from enumerated int to String String pwd; switch(pwdSpecialValue) { @@ -170,11 +80,8 @@ public byte[] generateToken(String uid, int pwdSpecialValue, int type, pwd = ProfileTokenImpl.PW_STR_NOPWDCHK; break; default: - Trace.log(Trace.ERROR, "Password special value = " + - pwdSpecialValue + " is not valid."); - throw new ExtendedIllegalArgumentException( - "Password special value", - ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); + Trace.log(Trace.ERROR, "Password special value = " + pwdSpecialValue + " is not valid."); + throw new ExtendedIllegalArgumentException("Password special value", ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); } // Only use SystemProgramCall code with password special values @@ -193,53 +100,43 @@ public byte[] generateToken(String uid, int pwdSpecialValue, int type, // Input: User password try { - parmlist[2] = new ProgramParameter( - CharConverter.stringToByteArray(37, sys, pwd)); + parmlist[2] = new ProgramParameter(CharConverter.stringToByteArray(37, sys, pwd)); } catch (java.io.UnsupportedEncodingException uee) { - Trace.log(Trace.ERROR, "Unexpected UnsupportedEncodingException: ", - uee); + Trace.log(Trace.ERROR, "Unexpected UnsupportedEncodingException: ", uee); throw new RetrieveFailedException(); } // Input: Timeout Interval - parmlist[3] = new ProgramParameter( - BinaryConverter.intToByteArray(timeoutInterval)); + parmlist[3] = new ProgramParameter(BinaryConverter.intToByteArray(timeoutInterval)); // Input: Profile token type - parmlist[4] = new ProgramParameter( - CharConverter.stringToByteArray(sys, - Integer.toString(type))); + parmlist[4] = new ProgramParameter(CharConverter.stringToByteArray(sys, Integer.toString(type))); - // Input/output: Error code. NULL. - parmlist[5] = new ProgramParameter(BinaryConverter.intToByteArray(0)); + // Input/output: Error code. NULL. + parmlist[5] = new ProgramParameter(BinaryConverter.intToByteArray(0)); - ProgramCall programCall = new ProgramCall(sys); + ProgramCall programCall = new ProgramCall(sys); - try { - programCall.setProgram( - QSYSObjectPathName.toPath("QSYS", "QSYGENPT", "PGM"), - parmlist); - programCall.suggestThreadsafe(); // Run on-thread if possible; allows app to use disabled profile. - if (!programCall.run()) { - Trace.log(Trace.ERROR, "Call to QSYGENPT failed."); - throw new RetrieveFailedException( - programCall.getMessageList()); - } - } - catch (java.io.IOException ioe) { - AuthenticationSystem.handleUnexpectedException(ioe); } - catch (java.beans.PropertyVetoException pve) { - AuthenticationSystem.handleUnexpectedException(pve); } - catch (InterruptedException ine) { - AuthenticationSystem.handleUnexpectedException(ine); } + try { + programCall.setProgram(QSYSObjectPathName.toPath("QSYS", "QSYGENPT", "PGM"), parmlist); + programCall.suggestThreadsafe(); // Run on-thread if possible; allows app to use disabled profile. + if (!programCall.run()) + { + Trace.log(Trace.ERROR, "Call to QSYGENPT failed."); + throw new RetrieveFailedException(programCall.getMessageList()); + } + } + catch (java.io.IOException|java.beans.PropertyVetoException|InterruptedException e) { + AuthenticationSystem.handleUnexpectedException(e); + } catch (Exception e) { - throw new RetrieveFailedException(); } + throw new RetrieveFailedException(); + } return parmlist[0].getOutputData(); } - //$A2 /** * Generates and returns a new profile token based on * the provided information using a password string @@ -278,16 +175,15 @@ public byte[] generateToken(String uid, int pwdSpecialValue, int type, * @deprecated Use generateTokenExtended(String uid, char[] pwd, int type, * int timeoutInterval) instead. */ - public byte[] generateTokenExtended(String uid, String pwd, int type, - int timeoutInterval) throws RetrieveFailedException { - + @Deprecated + public byte[] generateTokenExtended(String uid, String pwd, int type, int timeoutInterval) throws RetrieveFailedException + { // Use the AS400 object to obtain the token. // This will obtain the token by interacting with the IBM i // system signon server and avoid transmitting a cleartext password. byte[] tkn = null; try { - tkn = getCredential().getSystem().getProfileToken(uid, pwd, - type, timeoutInterval).getToken(); + tkn = getCredential().getSystem().getProfileToken(uid, pwd, type, timeoutInterval).getToken(); } catch (AS400SecurityException se) { throw new RetrieveFailedException(se.getReturnCode()); @@ -295,54 +191,19 @@ public byte[] generateTokenExtended(String uid, String pwd, int type, catch (Exception e) { AuthenticationSystem.handleUnexpectedException(e); } + return tkn; } - /** - * Generates and returns a new profile token based on - * the provided information using a password string - *

- * This method is used for generating a token using - * a password string (vs a special value). - * - * @param uid - * The name of the user profile for which the token - * is to be generated. - * - * @param pwd - * The user profile password. - * Special values are not supported by this method. - * - * @param type - * The type of token. - * Possible types are defined as fields on the - * ProfileTokenCredential class: - *

- *

- * - * @param timeoutInterval - * The number of seconds to expiration. - * - * @return - * The token bytes. - * - * @exception RetrieveFailedException - * If errors occur while generating the token. - * - */ - public byte[] generateTokenExtended(String uid, char[] pwd, int type, - int timeoutInterval) throws RetrieveFailedException { - + + @Override + public byte[] generateTokenExtended(String uid, char[] pwd, int type, int timeoutInterval) throws RetrieveFailedException + { // Use the AS400 object to obtain the token. // This will obtain the token by interacting with the IBM i // system signon server and avoid transmitting a cleartext password. byte[] tkn = null; try { - tkn = getCredential().getSystem().getProfileToken(uid, pwd, - type, timeoutInterval).getToken(); + tkn = getCredential().getSystem().getProfileToken(uid, pwd, type, timeoutInterval).getToken(); } catch (AS400SecurityException se) { throw new RetrieveFailedException(se.getReturnCode()); @@ -350,22 +211,11 @@ public byte[] generateTokenExtended(String uid, char[] pwd, int type, catch (Exception e) { AuthenticationSystem.handleUnexpectedException(e); } + return tkn; } - /** - * Returns the number of seconds before the - * credential is due to expire. - * - * @return - * The number of seconds before expiration; - * zero (0) if already expired. - * - * @exception RetrieveFailedException - * If errors occur while retrieving - * timeout information. - * - */ + @Override public int getTimeToExpiration() throws RetrieveFailedException { ProgramCall programCall = new ProgramCall(getCredential().getSystem()); @@ -377,22 +227,15 @@ public int getTimeToExpiration() throws RetrieveFailedException { parmlist[2] = new ProgramParameter(new AS400Bin4().toBytes(0)); try { - programCall.setProgram(QSYSObjectPathName.toPath("QSYS", - "QSYGETPT", "PGM"), parmlist); + programCall.setProgram(QSYSObjectPathName.toPath("QSYS", "QSYGETPT", "PGM"), parmlist); programCall.suggestThreadsafe(); // Run on-thread if possible. if (!programCall.run()) { Trace.log(Trace.ERROR, "Call to QSYGETPT failed."); throw new RetrieveFailedException(); } } - catch (java.io.IOException ioe) { - AuthenticationSystem.handleUnexpectedException(ioe); - } - catch (java.beans.PropertyVetoException pve) { - AuthenticationSystem.handleUnexpectedException(pve); - } - catch (InterruptedException ine) { - AuthenticationSystem.handleUnexpectedException(ine); + catch (java.io.IOException|java.beans.PropertyVetoException|InterruptedException e) { + AuthenticationSystem.handleUnexpectedException(e); } catch (Exception e) { throw new RetrieveFailedException(programCall.getMessageList()); @@ -401,85 +244,38 @@ public int getTimeToExpiration() throws RetrieveFailedException { return (new AS400Bin4()).toInt(parmlist[0].getOutputData()); } - /** - * Updates or extends the validity period for the credential. - * - *

Generates a new profile token based on the previously - * established token with the given type - * and timeoutInterval. - * - *

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 the - * ProfileTokenCredential class: - *

- *

- * - * @param timeoutInterval - * The number of seconds before expiration. - * - * @return - * The new token. - * - * @exception RefreshFailedException - * If errors occur during refresh. - * - */ - public byte[] refresh(int type, int timeoutInterval) - throws RefreshFailedException { - + @Override + public byte[] refresh(int type, int timeoutInterval) throws RefreshFailedException + { ProfileTokenCredential tgt = (ProfileTokenCredential)getCredential(); AS400 sys = tgt.getSystem(); ProgramCall programCall = new ProgramCall(tgt.getSystem()); ProgramParameter[] parmlist = new ProgramParameter[5]; - parmlist[0] = new ProgramParameter( - ProfileTokenCredential.TOKEN_LENGTH); - parmlist[1] = new ProgramParameter(new AS400ByteArray( - ProfileTokenCredential.TOKEN_LENGTH).toBytes( - tgt.getToken())); - parmlist[2] = new ProgramParameter( - new AS400Bin4().toBytes(timeoutInterval)); - parmlist[3] = new ProgramParameter(new AS400Text( - 1, sys.getCcsid(), sys).toBytes(Integer.toString(type))); + parmlist[0] = new ProgramParameter(ProfileTokenCredential.TOKEN_LENGTH); + parmlist[1] = new ProgramParameter(new AS400ByteArray(ProfileTokenCredential.TOKEN_LENGTH).toBytes(tgt.getToken())); + parmlist[2] = new ProgramParameter(new AS400Bin4().toBytes(timeoutInterval)); + parmlist[3] = new ProgramParameter(new AS400Text(1, sys.getCcsid(), sys).toBytes(Integer.toString(type))); parmlist[4] = new ProgramParameter(new AS400Bin4().toBytes(0)); try { - programCall.setProgram(QSYSObjectPathName.toPath("QSYS", - "QSYGENFT", "PGM"), parmlist); + programCall.setProgram(QSYSObjectPathName.toPath("QSYS", "QSYGENFT", "PGM"), parmlist); programCall.suggestThreadsafe(); // Run on-thread if possible. if (!programCall.run()) { Trace.log(Trace.ERROR, "Call to QSYGENFT failed."); throw new RefreshFailedException(); } } - catch (java.io.IOException ioe) { - AuthenticationSystem.handleUnexpectedException(ioe); - } - catch (java.beans.PropertyVetoException pve) { - AuthenticationSystem.handleUnexpectedException(pve); - } - catch (InterruptedException ine) { - AuthenticationSystem.handleUnexpectedException(ine); + catch (java.io.IOException|java.beans.PropertyVetoException|InterruptedException e) { + AuthenticationSystem.handleUnexpectedException(e); } catch (Exception e) { throw new RefreshFailedException(programCall.getMessageList()); } - return (byte[])new AS400ByteArray( - ProfileTokenCredential.TOKEN_LENGTH).toObject( - parmlist[0].getOutputData()); + return (byte[])new AS400ByteArray(ProfileTokenCredential.TOKEN_LENGTH).toObject(parmlist[0].getOutputData()); } - + /** * Removes the token from the IBM i system. * @@ -487,7 +283,8 @@ public byte[] refresh(int type, int timeoutInterval) * If errors occur while removing the credential. * */ - void removeFromSystem() throws DestroyFailedException { + void removeFromSystem() throws DestroyFailedException + { ProfileTokenCredential tgt = (ProfileTokenCredential)getCredential(); AS400 sys = tgt.getSystem(); ProgramCall programCall = new ProgramCall(sys); @@ -496,47 +293,38 @@ void removeFromSystem() throws DestroyFailedException { parmlist[0] = new ProgramParameter( new AS400Text(10, sys.getCcsid(), sys).toBytes("*PRFTKN")); parmlist[1] = new ProgramParameter(new AS400Bin4().toBytes(0)); - parmlist[2] = new ProgramParameter( - new AS400ByteArray( - ProfileTokenCredential.TOKEN_LENGTH).toBytes(tgt.getToken())); + parmlist[2] = new ProgramParameter(new AS400ByteArray(ProfileTokenCredential.TOKEN_LENGTH).toBytes(tgt.getToken())); - try { - programCall.setProgram(QSYSObjectPathName.toPath("QSYS", - "QSYRMVPT", "PGM"), parmlist); + try + { + programCall.setProgram(QSYSObjectPathName.toPath("QSYS", "QSYRMVPT", "PGM"), parmlist); programCall.suggestThreadsafe(); // Run on-thread if possible. if (!programCall.run()) { Trace.log(Trace.ERROR, "Call to QSYRMVPT failed."); throw new DestroyFailedException(); } } - catch (java.io.IOException ioe) { - AuthenticationSystem.handleUnexpectedException(ioe); - } - catch (java.beans.PropertyVetoException pve) { - AuthenticationSystem.handleUnexpectedException(pve); - } - catch (InterruptedException ine) { - AuthenticationSystem.handleUnexpectedException(ine); + catch (java.io.IOException|java.beans.PropertyVetoException|InterruptedException e) { + AuthenticationSystem.handleUnexpectedException(e); } catch (Exception e) { throw new DestroyFailedException(programCall.getMessageList()); } } - //$A2 /** * Convert Unicode string to EBCID CCSID 37 byte array. * Copied from com.ibm.as400.access.SignonConverter */ - private static byte[] stringToByteArray(String source) - throws RetrieveFailedException + private static byte[] stringToByteArray(String source) throws RetrieveFailedException { char[] sourceChars = source.toCharArray(); byte[] returnBytes = { (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40 }; - for (int i = 0; i < sourceChars.length; ++i) { + for (int i = 0; i < sourceChars.length; ++i) + { switch (sourceChars[i]) { case 0x0023: returnBytes[i] = (byte)0x7B; break; // # @@ -597,10 +385,11 @@ private static byte[] stringToByteArray(String source) case 0x00E0: returnBytes[i] = (byte)0x7C; break; // Cp297, a with grave. case 0x0130: returnBytes[i] = (byte)0x5B; break; // Cp905, I with over dot. case 0x015E: returnBytes[i] = (byte)0x7C; break; // Cp905, S with cedilla. - default: throw new RetrieveFailedException( - AS400SecurityException.SIGNON_CHAR_NOT_VALID); + + default: throw new RetrieveFailedException(AS400SecurityException.SIGNON_CHAR_NOT_VALID); } } + return returnBytes; } } From 40a9c814b64b0c13d0439c86dc6e825745983dce Mon Sep 17 00:00:00 2001 From: nadir amra <37912950+nadiramra@users.noreply.github.com> Date: Thu, 15 Aug 2024 23:25:33 -0500 Subject: [PATCH 2/2] Update IFSFile.java Signed-off-by: nadir amra <37912950+nadiramra@users.noreply.github.com> --- src/main/java/com/ibm/as400/access/IFSFile.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/ibm/as400/access/IFSFile.java b/src/main/java/com/ibm/as400/access/IFSFile.java index f1ecda988..1b4124eec 100644 --- a/src/main/java/com/ibm/as400/access/IFSFile.java +++ b/src/main/java/com/ibm/as400/access/IFSFile.java @@ -1895,7 +1895,7 @@ public int getASP() throws IOException, AS400SecurityException if (getSystem().getAuthenticationScheme() == AS400.AUTHENTICATION_SCHEME_PASSWORD || getSystem().getAuthenticationScheme()== AS400.AUTHENTICATION_SCHEME_GSS_TOKEN) - impl_.getASP(); + return impl_.getASP(); return -1; } @@ -1922,7 +1922,8 @@ else if (fileSystemType == 3) if (impl_ == null) chooseImpl(); - if (getSystem().getAuthenticationScheme() == AS400.AUTHENTICATION_SCHEME_PASSWORD) + if (getSystem().getAuthenticationScheme() == AS400.AUTHENTICATION_SCHEME_PASSWORD + || getSystem().getAuthenticationScheme()== AS400.AUTHENTICATION_SCHEME_GSS_TOKEN) return (retrieveAll) ? impl_.getFileSystemType(this.isDirectory()) : impl_.getFileSystemType(); return ""; @@ -1948,7 +1949,11 @@ else if (fileSystemType == 3) if (impl_ == null) chooseImpl(); - return (getSystem().getAuthenticationScheme() == AS400.AUTHENTICATION_SCHEME_PASSWORD) ? impl_.getFileSystemType() : ""; + if (getSystem().getAuthenticationScheme() == AS400.AUTHENTICATION_SCHEME_PASSWORD + || getSystem().getAuthenticationScheme()== AS400.AUTHENTICATION_SCHEME_GSS_TOKEN) + return impl_.getFileSystemType(); + + return ""; } /**