-
Notifications
You must be signed in to change notification settings - Fork 39
Set gss token #290
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Set gss token #290
Changes from all commits
b617acf
2974b5b
170690d
f54510e
3b81ea8
e929bef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -188,6 +188,9 @@ public class AS400ImplRemote implements AS400Impl | |
|
|
||
| private static final String CLASSNAME = "com.ibm.as400.access.AS400ImplRemote"; | ||
|
|
||
| // GSS Token, for Kerberos. | ||
| private CredentialVault kerbTicket_; | ||
|
|
||
| static { | ||
| if (Trace.traceOn_) | ||
| Trace.logLoadPath(CLASSNAME); | ||
|
|
@@ -665,10 +668,14 @@ public int createUserHandle() throws AS400SecurityException, IOException | |
| { | ||
| try | ||
| { | ||
| byte[] authenticationBytes = (gssCredential_ == null) | ||
| byte[] authenticationBytes; | ||
| if (!this.kerbTicket_.isEmpty()){ | ||
| authenticationBytes = this.kerbTicket_.getClearCredential(); | ||
| } else { | ||
| authenticationBytes = (gssCredential_ == null) | ||
| ? TokenManager.getGSSToken(systemName_, gssName_) | ||
| : TokenManager2.getGSSToken(systemName_, gssCredential_); | ||
| } | ||
| IFSUserHandle2Req req = new IFSUserHandle2Req(authenticationBytes, aafIndicator_ ? additionalAuthFactor_ : null); | ||
| ds = (ClientAccessDataStream) connectedServer.sendAndReceive(req); | ||
| } | ||
|
|
@@ -1016,9 +1023,13 @@ public void generateProfileToken(ProfileTokenCredential profileToken, String use | |
| case AS400.AUTHENTICATION_SCHEME_GSS_TOKEN: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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, This is more pure as it keeps the direct-kerb-ticket path and the GSS path separate |
||
| try | ||
| { | ||
| authenticationBytes = (gssCredential_ == null) | ||
| ? TokenManager.getGSSToken(systemName_, gssName) | ||
| : TokenManager2.getGSSToken(systemName_, gssCredential_); | ||
| if (!this.kerbTicket_.isEmpty()){ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
| authenticationBytes = this.kerbTicket_.getClearCredential(); | ||
| } else { | ||
| authenticationBytes = (gssCredential_ == null) | ||
| ? TokenManager.getGSSToken(systemName_, gssName) | ||
| : TokenManager2.getGSSToken(systemName_, gssCredential_); | ||
| } | ||
| } | ||
| catch (Exception e) | ||
| { | ||
|
|
@@ -1838,6 +1849,8 @@ byte[] getPassword(byte[] clientSeed, byte[] serverSeed) throws AS400SecurityExc | |
| if (credType == AS400.AUTHENTICATION_SCHEME_GSS_TOKEN) | ||
| { | ||
| try { | ||
| if (!kerbTicket_.isEmpty()) | ||
| return kerbTicket_.getClearCredential(); | ||
| return (gssCredential_ == null) | ||
| ? TokenManager.getGSSToken(systemName_, gssName_) | ||
| : TokenManager2.getGSSToken(systemName_, gssCredential_); | ||
|
|
@@ -2216,6 +2229,8 @@ private byte[] getDdmEncryptedPassword(byte[] sharedPrivateKey, byte[] serverSee | |
| if (credType == AS400.AUTHENTICATION_SCHEME_GSS_TOKEN) | ||
| { | ||
| try { | ||
| if (!kerbTicket_.isEmpty()) | ||
| return kerbTicket_.getClearCredential(); | ||
| return (gssCredential_ == null) | ||
| ? TokenManager.getGSSToken(systemName_, gssName_) | ||
| : TokenManager2.getGSSToken(systemName_, gssCredential_); | ||
|
|
@@ -5402,4 +5417,10 @@ else if (profileToken.getTokenCreator() != ProfileTokenCredential.CREATOR_SIGNON | |
| public String getLocalIPAddress() { | ||
| return localIPAddress_; | ||
| } | ||
|
|
||
| @Override | ||
| public void setKerbTicket(byte[] ticket) { | ||
| this.kerbTicket_ = new PasswordVault(ticket); | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -592,6 +592,7 @@ public void close () | |
|
|
||
|
|
||
| as400_.disconnectServer (server_); | ||
|
|
||
| server_ = null; | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
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_PREFIXis 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/filesSo 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:
KERBEROS_PREFIXlogic from the toolbox entirelyisKerbTicket()) into the Mapepire server code itself. Changes may be able to be fully contained within this method: https://github.com/Mapepire-IBMi/mapepire-server/blob/9c9a3e2c866d80dd8551dbba6e11842c4a240494/src/main/java/com/github/ibm/mapepire/SystemConnection.java#L114@julesyan + @nadiramra , thoughts?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
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:
Cons:
Option 2: change mapepire-server to not use DriverManager interfaces
Pros:
Cons:
Option 3: create a new JDBC property for kerberos ticket (I believe this is best)
Pros:
Cons:
@julesyan / @nadiramra / @jeber-ibm , thoughts?