Skip to content

Commit

Permalink
JDBC AAF
Browse files Browse the repository at this point in the history
  • Loading branch information
jeber-ibm authored and ThePrez committed Dec 13, 2023
1 parent 07648cb commit 78a6b48
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 36 deletions.
70 changes: 52 additions & 18 deletions src/main/java/com/ibm/as400/access/AS400JDBCDataSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ public class AS400JDBCDataSource
public AS400JDBCDataSource()
{
initializeTransient();
properties_ = new JDProperties(null, null, null);
properties_ = new JDProperties(null, null, null, null);
sockProps_ = new SocketProperties();
}

Expand Down Expand Up @@ -270,6 +270,24 @@ public AS400JDBCDataSource(String serverName, String user, char[] password)
setPassword(password);
}

/**
* Constructs an AS400JDBCDataSource object with the specified signon information.
* @param serverName The name of the IBM i system.
* @param user The user id.
* @param password The user password. The caller is responsible for clearing password after the constructor returns.
* @param additionalAuthenticationFactor. The additional authentication factor. The user must call connect() before
* the additional authentication factor expires.
**/
public AS400JDBCDataSource(String serverName, String user, char[] password, char[] additionalAuthenticationFactor)
{
this();

setServerName(serverName);
setUser(user);
setPassword(password);
setAdditionalAuthenticationFactor(additionalAuthenticationFactor);
}


//@K1A
/**
Expand Down Expand Up @@ -339,7 +357,7 @@ public AS400JDBCDataSource(String serverName, String user, String password,
}

// must initialize the JDProperties so the property change checks dont get a NullPointerException
properties_ = new JDProperties(null, null,null);
properties_ = new JDProperties(null, null,null,null);

Properties properties = new Properties();
sockProps_ = new SocketProperties();
Expand Down Expand Up @@ -412,7 +430,7 @@ else if (property.equals(SOCKET_TCP_NO_DELAY)) {
properties.put(property, value);
}
}
properties_ = new JDProperties(properties, null, null);
properties_ = new JDProperties(properties, null, null, null);

// get the prompt property and set it back in the as400 object
String prmpt = properties_.getString(JDProperties.PROMPT);
Expand Down Expand Up @@ -568,18 +586,29 @@ public String getCharacterTruncation() {


/**
* Returns the database connection.
* Returns the database connection. If an additional authentication factor is needed for the connection,
* then setAdditionalAuthenciationFactor must be called immediately before this method.
* @return The connection.
* @exception SQLException If a database error occurs.
**/
public Connection getConnection() throws SQLException
{
//if the user asks for the object
//to be secure, clone a SecureAS400 object; otherwise, clone an AS400 object
if (isSecure_ || isSecure()) //@B4A //@C2C
return getConnection(new SecureAS400(as400_)); //@B4A
else //@B4A
return getConnection(new AS400(as400_));
char[] aaf = properties_.getAdditionalAuthenticationFactor();
if (isSecure_ || isSecure()) { //@B4A //@C2C
SecureAS400 newAs400 = new SecureAS400(as400_);
if (aaf != null) {
newAs400.setAdditionalAuthenticationFactor(aaf);
}
return getConnection(newAs400); //@B4A
} else { //@B4A
AS400 newAs400 = new AS400(as400_);
if (aaf != null) {
newAs400.setAdditionalAuthenticationFactor(aaf);
}
return getConnection(newAs400);
}
}


Expand Down Expand Up @@ -623,7 +652,7 @@ public Connection getConnection(String user, char[] password) throws SQLExceptio


/**
* Returns the database connection using the specified <i>user</i> and <i>password</i>.
* Returns the database connection using the specified <i>user</i> and <i>password</i> and <i>additionalAuthenticationFactor</i>.
* @param user The database user.
* @param password The database password.
* @param additionalAuthenticationFactor The additional authentication factor, or null if not providing one
Expand Down Expand Up @@ -701,14 +730,19 @@ public Connection getConnection(String user, char[] password, char[] additionalA

//if the user asks for the object
//to be secure, clone a SecureAS400 object; otherwise, clone an AS400 object
if (isSecure_ || isSecure()) //@C2A
{ //@C2A
as400Object = new SecureAS400(getServerName(), user, password); //@C2A
} //@C2A
else
{ //@C2A //@C2A
as400Object = new AS400(getServerName(), user, password); //@C2A
} //@C2A
try {
if (isSecure_ || isSecure()) { // @C2A
as400Object = new SecureAS400(getServerName(), user, password, additionalAuthenticationFactor); // @C2A
} else { // @C2A //@C2A
as400Object = new AS400(getServerName(), user, password, additionalAuthenticationFactor); // @C2A
} // @C2A
} catch (AS400SecurityException e) {
JDError.throwSQLException(this, JDError.EXC_CONNECTION_REJECTED, e);
throw new SQLException("PREVENT COMPILER ERROR"); /* Dead code */
} catch (IOException e) {
JDError.throwSQLException(this, JDError.EXC_CONNECTION_UNABLE, e);
throw new SQLException("PREVENT COMPILER ERROR"); /* Dead code */
}

try //@PDA
{ //@PDA
Expand Down Expand Up @@ -2202,7 +2236,7 @@ public void setAccess(String access)
* @param additionalAuthenticationFactor the additional authentication factor, or null if not providing one
*/
public void setAdditionalAuthenticationFactor(char[] additionalAuthenticationFactor) {

properties_.setAdditionalAuthenticationFactor(additionalAuthenticationFactor);
}

//@AC1
Expand Down
28 changes: 20 additions & 8 deletions src/main/java/com/ibm/as400/access/AS400JDBCDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package com.ibm.as400.access;

import java.beans.PropertyVetoException; // @B9A
import java.io.IOException;
import java.net.InetAddress; // @C2A
import java.sql.Connection;
import java.sql.Driver;
Expand Down Expand Up @@ -259,7 +260,7 @@ public java.sql.Connection connect (String url, String userid, char[] password,
{
Properties properties = new Properties();
properties.put("user", userid);
return connect(url, properties, password);
return connect(url, properties, password, additionalAuthenticationFactor);
}


Expand Down Expand Up @@ -502,7 +503,7 @@ else if (JDProperties.isToolboxTraceSet (urlProperties, info) == JDProperties.TR
JDTrace.logInformation (this,"connect called with URL: "+traceUrl);
}

JDProperties jdProperties = new JDProperties (urlProperties, info, password);
JDProperties jdProperties = new JDProperties (urlProperties, info, password, additionalAuthenticationFactor);

// Initialize the connection if the URL is valid.
Connection connection = null; //@A0C
Expand Down Expand Up @@ -999,7 +1000,7 @@ public DriverPropertyInfo[] getPropertyInfo (String url,
DriverPropertyInfo[] dpi = null;
if (dataSourceUrl.isValid ())
{
JDProperties properties = new JDProperties (dataSourceUrl.getProperties(), info, null);
JDProperties properties = new JDProperties (dataSourceUrl.getProperties(), info, null, null);
dpi = properties.getInfo ();
}

Expand Down Expand Up @@ -1096,6 +1097,7 @@ static AS400 initializeAS400(JDDataSourceURL dataSourceUrl,
String serverName = dataSourceUrl.getServerName();
String userName = jdProperties.getString (JDProperties.USER);
char[] clearPassword = jdProperties.getClearPassword();
char[] additionalAuthenticationFactor = jdProperties.getAdditionalAuthenticationFactor();
String prompt = jdProperties.getString (JDProperties.PROMPT); // @B8C
boolean secure = jdProperties.getBoolean (JDProperties.SECURE);
boolean useThreads = jdProperties.getBoolean(JDProperties.THREAD_USED);
Expand Down Expand Up @@ -1183,6 +1185,7 @@ static AS400 initializeAS400(JDDataSourceURL dataSourceUrl,

// Create the AS400 object, so we can create a Connection via loadImpl2.
AS400 as400 = null;
try {
if (secure)
{
if (serverName.length() == 0)
Expand All @@ -1192,7 +1195,7 @@ else if (userName == null )
else if (clearPassword == null )
as400 = new SecureAS400 (serverName, userName);
else
as400 = new SecureAS400 (serverName, userName, clearPassword);
as400 = new SecureAS400 (serverName, userName, clearPassword, additionalAuthenticationFactor);

}
else
Expand All @@ -1204,9 +1207,18 @@ else if ((userName == null) || (userName.length() == 0))
else if (clearPassword == null )
as400 = new AS400 (serverName, userName);
else
as400 = new AS400 (serverName, userName, clearPassword);
// Note: If additionalAuthenticationFactor is specified then a connection to the
// signon server will immediately be established.
as400 = new AS400 (serverName, userName, clearPassword, additionalAuthenticationFactor);
}

} catch (AS400SecurityException e)
{
JDError.throwSQLException (as400, JDError.EXC_CONNECTION_REJECTED, e);
}
catch (IOException e)
{
JDError.throwSQLException (as400, JDError.EXC_CONNECTION_UNABLE, e);
}
if (clearPassword != null) {
CredentialVault.clearArray(clearPassword);
}
Expand Down Expand Up @@ -1369,7 +1381,7 @@ private Connection initializeConnection (AS400 as400)
{
JDDataSourceURL dataSourceUrl = new JDDataSourceURL(null);
Properties info = new Properties();
JDProperties jdProperties = new JDProperties(null, info, null);
JDProperties jdProperties = new JDProperties(null, info, null, null);

//@B6C Moved common code to prepareConnection.
return prepareConnection(as400, dataSourceUrl, jdProperties);
Expand All @@ -1389,7 +1401,7 @@ private Connection initializeConnection (String schema, Properties info, AS400 a
url = "jdbc:as400://" + as400.getSystemName(); //@B6A
JDDataSourceURL dataSourceUrl = new JDDataSourceURL(url);

JDProperties jdProperties = new JDProperties(null, info, null);
JDProperties jdProperties = new JDProperties(null, info, null, null);

if (JDTrace.isTraceOn())
JDTrace.logInformation (this, "Using IBM Toolbox for Java JDBC driver implementation");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ else if (isConnectionPoolDataSource &&
}
} // 'while' loop

properties_ = new JDProperties(properties, null, null);
properties_ = new JDProperties(properties, null, null, null);
if (sockProps_.isAnyOptionSet()) { // only need to set if not default
as400_.setSocketProperties(sockProps_);
}
Expand Down
44 changes: 35 additions & 9 deletions src/main/java/com/ibm/as400/access/JDProperties.java
Original file line number Diff line number Diff line change
Expand Up @@ -178,19 +178,18 @@ public class JDProperties implements Serializable, Cloneable //@PDC 550
static final int ENABLE_SEAMLESS_FAILOVER = 98;
static final int AFFINITY_FAILBACK_INTERVAL = 99;
static final int TCP_NO_DELAY = 100;
static final int ADDITIONAL_AUTHENTICATION_FACTOR=101;
static final int STAY_ALIVE = 102;

// @W2 always add to the end of the array!

private static final int NUMBER_OF_ATTRIBUTES_ = 101; // @A0C @C1C @A3A @D0C @E0C
// @E1C @D1c @E2C @E3C @E9C @F1C
// @W1c @j1c @J2c @F5C @F6C @F7c @M0C @K1C @K2C @K5C @KBC @K24 @KBL @K94 @K54 @540 @PDC
// @PDC @550 @DFA @CE1 @AC1 @igwrn @pw3 @cc1 @DMY @STIMEOUT
// @A2C @A6C @F6A@R3
private static final int NUMBER_OF_ATTRIBUTES_ = 103;


// Property names.
private static final String ACCESS_ = "access";
private static final String AFFINITY_FAILBACK_INTERVAL_ = "affinityFailbackInterval";
private static final String ADDITIONAL_AUTHENTICATION_FACTOR_ = "additionalAuthenticationFactor";
private static final String BEHAVIOR_OVERRIDE_ = "behavior override"; // @F7A
private static final String BIDI_STRING_TYPE_ = "bidi string type"; // @E9A
private static final String BIG_DECIMAL_ = "big decimal"; // @E0A
Expand Down Expand Up @@ -249,6 +248,7 @@ public class JDProperties implements Serializable, Cloneable //@PDC 550
private static final String SORT_LANGUAGE_ = "sort language";
private static final String SORT_TABLE_ = "sort table";
private static final String SORT_WEIGHT_ = "sort weight";
private static final String STAY_ALIVE_ = "stay alive";
private static final String TCP_NO_DELAY_ = "tcp no delay";
private static final String THREAD_USED_ = "thread used"; // @E1A
private static final String TIME_FORMAT_ = "time format";
Expand Down Expand Up @@ -534,7 +534,7 @@ public class JDProperties implements Serializable, Cloneable //@PDC 550
private boolean extra_;
private String[] values_;
private Properties info_; // @A3A

private char[] additionalAuthenticationFactor_;


private PasswordVault passwordVault_;
Expand Down Expand Up @@ -1639,8 +1639,20 @@ public class JDProperties implements Serializable, Cloneable //@PDC 550
dpi_[i].choices[3] = DECIMAL_DATA_ERRORS_REPORT_NULL;
defaults_[i] = EMPTY_;


i = ADDITIONAL_AUTHENTICATION_FACTOR;
dpi_[i] = new DriverPropertyInfo (ADDITIONAL_AUTHENTICATION_FACTOR_, "");
dpi_[i].description = "ADDITIONAL_AUTHENTICATION_FACTOR_DESC";
dpi_[i].required = false;
dpi_[i].choices = new String[0];
defaults_[i] = EMPTY_;

i = STAY_ALIVE;
dpi_[i] = new DriverPropertyInfo (STAY_ALIVE_, "");
dpi_[i].description = "STAY_ALIVE_DESC";
dpi_[i].required = false;
dpi_[i].choices = new String[0];
defaults_[i] = "0";


}

Expand All @@ -1650,7 +1662,7 @@ public class JDProperties implements Serializable, Cloneable //@PDC 550
**/
JDProperties ()
{
this(null, null,null);
this(null, null,null,null);
}

/**
Expand All @@ -1659,7 +1671,7 @@ public class JDProperties implements Serializable, Cloneable //@PDC 550
@param urlProperties The URL properties.
@param info The info properties.
**/
JDProperties (Properties urlProperties, Properties info, char[] password)
JDProperties (Properties urlProperties, Properties info, char[] password, char[] additionalAuthenticationFactor)
{
// Initialize the values.
info_ = info;
Expand All @@ -1679,6 +1691,13 @@ public class JDProperties implements Serializable, Cloneable //@PDC 550
passwordVault_ = new PasswordVault(password);
}

if (additionalAuthenticationFactor == null) {
String aaf = getProperty (urlProperties, info, "additionalAuthenticationFactor");
if (aaf != null) {
additionalAuthenticationFactor = aaf.toCharArray();
}
}
additionalAuthenticationFactor_ = additionalAuthenticationFactor;
values_ = new String[NUMBER_OF_ATTRIBUTES_];
for (int i = 0; i < NUMBER_OF_ATTRIBUTES_; ++i) {
if (i != PASSWORD) { /*@AI7A*/
Expand Down Expand Up @@ -2242,6 +2261,13 @@ public String toString ()
return sb.toString();
}

public char[] getAdditionalAuthenticationFactor() {
return additionalAuthenticationFactor_;
}

public void setAdditionalAuthenticationFactor(char[] additionalAuthenticationFactor) {
additionalAuthenticationFactor_ = additionalAuthenticationFactor;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ <h3>General properties</h3>
<TH ID="cat1t4">Choices</TH>
<TH ID="cat1t5">Default</TH>
</TR>
<TR VALIGN="TOP">
<TD HEADERS="cat1">&quot;additionalAuthenticationFactor&quot;</TD>
<TD HEADERS="cat1t2">Specifies the additional authentication factor for connecting to the system.</TD>
<TD HEADERS="cat1t3" ALIGN="CENTER">no</TD>
<TD HEADERS="cat1t4">Authentication factor</TD>
<TD HEADERS="cat1t5">Unset</TD>
</TR>
<TR VALIGN="TOP">
<TD HEADERS="cat1">&quot;password&quot;</TD>
<TD HEADERS="cat1t2">Specifies the password for connecting to the system. If none is specified,
Expand Down Expand Up @@ -1408,6 +1415,15 @@ <h3>Other properties</h3>
</TD>
<TD HEADERS="cat6t5">&quot;0&quot;</TD>
</TR>
<TR VALIGN="TOP">
<TD HEADERS="cat6">&quot;stay alive&quot;</TD>
<TD HEADERS="cat6t2">If greater than 0, specifies the number of milliseconds between requests to the
database host server to keep the connection alive. </TD>
<TD HEADERS="cat6t3" ALIGN="CENTER">no</TD>
<TD HEADERS="cat6t4">&quot;0 <br>Positive millisecond value&quot;<BR>
&quot;false&quot;</TD>
<TD HEADERS="cat6t5">0</TD>
</TR>
<TR VALIGN="TOP">
<TD HEADERS="cat6">&quot;thread used&quot;</TD>
<TD HEADERS="cat6t2">Specifies whether threads should be used in communication
Expand Down

0 comments on commit 78a6b48

Please sign in to comment.