Skip to content

Conversation

@julesyan
Copy link
Member

@julesyan julesyan commented Dec 1, 2025

Updated PR of #279

Copy link
Member

@nadiramra nadiramra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure I like what is being done here - the mixing of password and GSS token is not good.

Copy link
Member

@ThePrez ThePrez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two main changes requested, see individual comments

@@ -1016,9 +1023,13 @@ public void generateProfileToken(ProfileTokenCredential profileToken, String use
case AS400.AUTHENTICATION_SCHEME_GSS_TOKEN:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What we really should do is define a new constant and associated switch case here, AS400.AUTHENTICATION_SCHEME_KRB_TICKET

This is more pure as it keeps the direct-kerb-ticket path and the GSS path separate

authenticationBytes = (gssCredential_ == null)
? TokenManager.getGSSToken(systemName_, gssName)
: TokenManager2.getGSSToken(systemName_, gssCredential_);
if (!this.kerbTicket_.isEmpty()){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this change (and other similar changes) would slide into the new switch statement(s) for AUTHENTICATION_SCHEME_KRB_TICKET mentioned in other review comment

private transient CredentialVault kerbTicket_;

// Prefix used to indicate that the password contains a base64-encoded Kerberos token.
public static final String KERBEROS_PREFIX = "_KERBEROSAUTH_";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole logic around KERBEROS_PREFIX is actually a pretty cool feature, but it still seems non-optimal to conflate kerberos tickets with the password.

As implemented, it allows non-programmatic connections like JDBC to use a kerberos ticket, very useful.

More importantly, the Mapepire client uses this new _KERBEROSAUTH_ scheme. See https://github.com/Mapepire-IBMi/mapepire-python/pull/84/files

So if we redesign this, we need to also redesign the Mapepire client, or at least the Mapepire server (middleware). In the Mapepire case, the ultimate constraining factor is that we're passing this through an HTTP basic auth mechanism which only supports userid and password. Hence the reason the prefix was invented. It's hacky and potentially problematic in the unlikely case someone has a password starting with this prefix, but it's honestly the best we can do.

My intuition says we should do the following:

@julesyan + @nadiramra , thoughts?

Copy link
Member

@ThePrez ThePrez Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I started looking at pulling the necessary changes into the mapepire-server project, but it's more complex than initially thought. Mapepire-server gets its connection through DriverManager.getConnection() which has no support for sending a kerberos token.

I see why it was implemented in this way, to support Kerberos through the standard DriverManager classes. Which I still assert is a useful feature.

So I think this boils down to three high-level options:

Option 1: existing implementation
Pros:

  • We know it works, and it covers all our bases

Cons:

  • conflates kerberos ticket and password

Option 2: change mapepire-server to not use DriverManager interfaces
Pros:

  • Pretty easy to implement
  • keeps password and kerberos ticket separate

Cons:

  • Creates a dual maintenance path for future versions of the server if we exoect to leverage other JDBC drivers
  • Makes use of native JDBC driver more complicated
  • If we've made it this far, we might as well publish a new feature of JDBC support for kerberos!

Option 3: create a new JDBC property for kerberos ticket (I believe this is best)
Pros:

  • keeps password and kerberos ticket separate
  • unlikely to have backward/forward compatibility issues

Cons:

  • Adding a new connection property is more involved

@julesyan / @nadiramra / @jeber-ibm , thoughts?

private transient CredentialVault kerbTicket_;

// Prefix used to indicate that the password contains a base64-encoded Kerberos token.
public static final String KERBEROS_PREFIX = "_KERBEROSAUTH_";
Copy link
Member

@ThePrez ThePrez Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I started looking at pulling the necessary changes into the mapepire-server project, but it's more complex than initially thought. Mapepire-server gets its connection through DriverManager.getConnection() which has no support for sending a kerberos token.

I see why it was implemented in this way, to support Kerberos through the standard DriverManager classes. Which I still assert is a useful feature.

So I think this boils down to three high-level options:

Option 1: existing implementation
Pros:

  • We know it works, and it covers all our bases

Cons:

  • conflates kerberos ticket and password

Option 2: change mapepire-server to not use DriverManager interfaces
Pros:

  • Pretty easy to implement
  • keeps password and kerberos ticket separate

Cons:

  • Creates a dual maintenance path for future versions of the server if we exoect to leverage other JDBC drivers
  • Makes use of native JDBC driver more complicated
  • If we've made it this far, we might as well publish a new feature of JDBC support for kerberos!

Option 3: create a new JDBC property for kerberos ticket (I believe this is best)
Pros:

  • keeps password and kerberos ticket separate
  • unlikely to have backward/forward compatibility issues

Cons:

  • Adding a new connection property is more involved

@julesyan / @nadiramra / @jeber-ibm , thoughts?

@nadiramra
Copy link
Member

nadiramra commented Dec 30, 2025 via email

@jeber-ibm
Copy link
Member

After some thought, I prefer using the password char[] parameter to pass the kerberos ticket.

The main problem that I am worried about is passing kerberos tickets as strings. In Java, the storage associated with a string cannot be forcefully cleared. If a kerberos ticket is stored as a string, then it may reside in memory for a long time and can be found by an attacker scanning the memory. Also, if the driver is storing a kerberos ticket, it should be encrypted or obfuscated so it cannot be easily found.

I thought about passing an encrypted ticket as a property and the encryption key as a property. However, if the two properties are passed using the same string, we will still have an attack vector that can easily be exploited.

If we pass the kerberbos ticket using the existing char[] password support, then the ticket can be cleared from memory and the ticket can be obfuscated like the password currently is.

@nadiramra
Copy link
Member

Again, not a fan of dual use parameters for authentication. Always can create a new method that extends password for gss tokens or add a new method that and infrastructure to mirror password support for kerberos tickets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants