Skip to content
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

8215916: The failure reason of an optional JAAS LoginModule is not logged #9159

Closed
wants to merge 24 commits into from

Conversation

jhuttana
Copy link
Contributor

@jhuttana jhuttana commented Jun 14, 2022

Could you please review the changes?
This patch is to address : https://bugs.openjdk.org/browse/JDK-8215916?jql=labels%20%3D%20starter-bug


Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Issue

  • JDK-8215916: The failure reason of an optional JAAS LoginModule is not logged

Reviewers

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk pull/9159/head:pull/9159
$ git checkout pull/9159

Update a local copy of the PR:
$ git checkout pull/9159
$ git pull https://git.openjdk.org/jdk pull/9159/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 9159

View PR using the GUI difftool:
$ git pr show -t 9159

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/9159.diff

@bridgekeeper bridgekeeper bot added the oca Needs verification of OCA signatory status label Jun 14, 2022
@bridgekeeper
Copy link

bridgekeeper bot commented Jun 14, 2022

Hi @jhuttana, welcome to this OpenJDK project and thanks for contributing!

We do not recognize you as Contributor and need to ensure you have signed the Oracle Contributor Agreement (OCA). If you have not signed the OCA, please follow the instructions. Please fill in your GitHub username in the "Username" field of the application. Once you have signed the OCA, please let us know by writing /signed in a comment in this pull request.

If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please use "Add GitHub user jhuttana" as summary for the issue.

If you are contributing this work on behalf of your employer and your employer has signed the OCA, please let us know by writing /covered in a comment in this pull request.

@jhuttana
Copy link
Contributor Author

/covered

@bridgekeeper bridgekeeper bot added the oca-verify Needs verification of OCA signatory status label Jun 14, 2022
@bridgekeeper
Copy link

bridgekeeper bot commented Jun 14, 2022

Thank you! Please allow for a few business days to verify that your employer has signed the OCA. Also, please note that pull requests that are pending an OCA check will not usually be evaluated, so your patience is appreciated!

@openjdk
Copy link

openjdk bot commented Jun 14, 2022

@jhuttana The following label will be automatically applied to this pull request:

  • security

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added the security security-dev@openjdk.org label Jun 14, 2022
@jhuttana jhuttana changed the title The failure reason of an optional JAAS LoginModule is not logged 8215916: The failure reason of an optional JAAS LoginModule is not logged Jun 14, 2022
@bridgekeeper bridgekeeper bot removed oca Needs verification of OCA signatory status oca-verify Needs verification of OCA signatory status labels Jun 21, 2022
@openjdk openjdk bot added the rfr Pull request is ready for review label Jun 21, 2022
ite.printStackTrace
(new java.io.PrintWriter(sw));
sw.flush();
le = new LoginException(sw.toString());
Copy link
Member

Choose a reason for hiding this comment

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

@wangweij might have more to say, but I think you just want to dump this information using debug.println if debug is enabled.

Copy link
Contributor

Choose a reason for hiding this comment

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

I have the same suggestion as Sean. In JAAS, login could succeed even if one optional LoginModule failed, and in this case the reason for that failure is lost (even with your current fix). Logging it somewhere might help developer understand why it happened.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks you both for taking a look at this PR.
I will investigate further for suitable suggested changes.
Could you please suggest me how I can quickly check whether the changes I made are reflecting properly as expected ?

Copy link
Contributor

Choose a reason for hiding this comment

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

There are several builtin LoginModule implementations inside OpenJDK. For example, you can configure both NTLoginModule and UnixLoginModule as OPTIONAL in your JAAS login configuration file. No matter if you run on Windows or Linux, one will succeed and one will fail but overall the login will succeed. You can set -Djava.security.debug=logincontext to see if there is information on the failed one.

Copy link
Contributor

@wangweij wangweij Jun 22, 2022

Choose a reason for hiding this comment

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

Also, if you like, try writing this as a regression test. You can call System.setErr at the beginning to redirect the log messages to your own ByteArrayOutputStream, and then after restoring the original System.err, you can inspect the output to see if the expected log message is there. This is not necessary since the code change is not significant.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@wangweij Thank you I will try these.

@jhuttana
Copy link
Contributor Author

jhuttana commented Jul 7, 2022

I verified the changes with sample example here: https://web.mit.edu/java_v1.5.0_22/distrib/share/docs/guide/security/jaas/tutorials/GeneralAcnOnly.html , before and after the patch.

Results are below:
Before Patch:

# ./build/linux-x86_64-server-release/images/jdk/bin/javac sample/SampleAcn.java sample/module/SampleLoginModule.java sample/principal/SamplePrincipal.java
# ./build/linux-x86_64-server-release/images/jdk/bin/java -Djava.security.auth.login.config==sample_jaas.config -Djava.security.debug=logincontext sample.SampleAcn
	[LoginContext]: Build ServiceProviders cache for ClassLoader: app
	[LoginContext]: Discovered ServiceProviders for ClassLoader: app
java.util.ServiceLoader$ProviderImpl@d5ed6ed
java.util.ServiceLoader$ProviderImpl@15a76bb1
java.util.ServiceLoader$ProviderImpl@307eace9
java.util.ServiceLoader$ProviderImpl@f50ec023
java.util.ServiceLoader$ProviderImpl@fdf98634
java.util.ServiceLoader$ProviderImpl@c2632fde
java.util.ServiceLoader$ProviderImpl@994f9a60
	[LoginContext]: sample.module.SampleLoginModule loaded via reflection
user name: testUser
password: test
		[SampleLoginModule] user entered user name: testUser
		[SampleLoginModule] user entered password: test
		[SampleLoginModule] authentication failed
	[LoginContext]: login OPTIONAL failure
	[LoginContext]: abort ignored
Authentication failed:
  Password Incorrect
user name: test
password: testPassword
		[SampleLoginModule] user entered user name: test
		[SampleLoginModule] user entered password: testPassword
		[SampleLoginModule] authentication failed
	[LoginContext]: login OPTIONAL failure
	[LoginContext]: abort ignored
Authentication failed:
  User Name Incorrect
user name: testUser
password: test
		[SampleLoginModule] user entered user name: testUser
		[SampleLoginModule] user entered password: test
		[SampleLoginModule] authentication failed
	[LoginContext]: login OPTIONAL failure
	[LoginContext]: abort ignored
Authentication failed:
  Password Incorrect

Sorry

After Patch:

# ./build/linux-x86_64-server-release/images/jdk/bin/javac sample/SampleAcn.java sample/module/SampleLoginModule.java sample/principal/SamplePrincipal.java
# ./build/linux-x86_64-server-release/images/jdk/bin/java -Djava.security.auth.login.config==sample_jaas.config -Djava.security.debug=logincontext sample.SampleAcn
	[LoginContext]: Build ServiceProviders cache for ClassLoader: app
	[LoginContext]: Discovered ServiceProviders for ClassLoader: app
java.util.ServiceLoader$ProviderImpl@8533fe57
java.util.ServiceLoader$ProviderImpl@1718814c
java.util.ServiceLoader$ProviderImpl@49c41191
java.util.ServiceLoader$ProviderImpl@55608305
java.util.ServiceLoader$ProviderImpl@ee04ebce
java.util.ServiceLoader$ProviderImpl@52aed7a2
java.util.ServiceLoader$ProviderImpl@6214285b
	[LoginContext]: sample.module.SampleLoginModule loaded via reflection
user name: test
password: testPassword
		[SampleLoginModule] user entered user name: test
		[SampleLoginModule] user entered password: testPassword
		[SampleLoginModule] authentication failed
	[LoginContext]: login OPTIONAL failure
	[LoginContext]: abort ignored
Authentication failed:
  javax.security.auth.login.FailedLoginException: User Name Incorrect
	at sample.module.SampleLoginModule.login(SampleLoginModule.java:214)
	at java.base/javax.security.auth.login.LoginContext.invoke(LoginContext.java:755)
	at java.base/javax.security.auth.login.LoginContext$4.run(LoginContext.java:679)
	at java.base/javax.security.auth.login.LoginContext$4.run(LoginContext.java:677)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
	at java.base/javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:677)
	at java.base/javax.security.auth.login.LoginContext.login(LoginContext.java:587)
	at sample.SampleAcn.main(SampleAcn.java:87)

user name: testUser
password: test
		[SampleLoginModule] user entered user name: testUser
		[SampleLoginModule] user entered password: test
		[SampleLoginModule] authentication failed
	[LoginContext]: login OPTIONAL failure
	[LoginContext]: abort ignored
Authentication failed:
  javax.security.auth.login.FailedLoginException: Password Incorrect
	at sample.module.SampleLoginModule.login(SampleLoginModule.java:216)
	at java.base/javax.security.auth.login.LoginContext.invoke(LoginContext.java:755)
	at java.base/javax.security.auth.login.LoginContext$4.run(LoginContext.java:679)
	at java.base/javax.security.auth.login.LoginContext$4.run(LoginContext.java:677)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
	at java.base/javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:677)
	at java.base/javax.security.auth.login.LoginContext.login(LoginContext.java:587)
	at sample.SampleAcn.main(SampleAcn.java:87)

user name: test
password: test
		[SampleLoginModule] user entered user name: test
		[SampleLoginModule] user entered password: test
		[SampleLoginModule] authentication failed
	[LoginContext]: login OPTIONAL failure
	[LoginContext]: abort ignored
Authentication failed:
  javax.security.auth.login.FailedLoginException: User Name Incorrect
	at sample.module.SampleLoginModule.login(SampleLoginModule.java:214)
	at java.base/javax.security.auth.login.LoginContext.invoke(LoginContext.java:755)
	at java.base/javax.security.auth.login.LoginContext$4.run(LoginContext.java:679)
	at java.base/javax.security.auth.login.LoginContext$4.run(LoginContext.java:677)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
	at java.base/javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:677)
	at java.base/javax.security.auth.login.LoginContext.login(LoginContext.java:587)
	at sample.SampleAcn.main(SampleAcn.java:87)

Sorry

After the patch it is printing the stack trace.

@wangweij
Copy link
Contributor

wangweij commented Jul 7, 2022

It will be nice if the test itself can confirm the correctness since this is not a manual test (and we definitely want to avoid manual test as much as possible). Also, tests in OpenJDK are meant to be launched by the jtreg command instead of javac/java it. Read https://openjdk.org/jtreg/ for more details.

@jhuttana
Copy link
Contributor Author

jhuttana commented Jul 7, 2022

Ok. So the steps what I followed to confirm the patch can be converted to test case?

@wangweij
Copy link
Contributor

wangweij commented Jul 7, 2022

Yes, or you can write an individual test.

@jhuttana
Copy link
Contributor Author

jhuttana commented Jul 8, 2022

Looks like already the test cases which serve our purpose to test our patch are already here: https://github.com/openjdk/jdk/tree/master/test/jdk/javax/security/auth/login/LoginContext
For eg: https://github.com/openjdk/jdk/blob/master/test/jdk/javax/security/auth/login/LoginContext/SmartLoginModule.java
We just have to add @test @bug and @run etc to pick this up for execution. Not sure why it was not done earlier.

I just tried executing the below set of test cases ( with or without the patch the result is same as SmartLoginModule.java , to me looks like not executed)

# jtreg/bin/jtreg -jdk:/root/jdk/build.8215916/linux-x86_64-server-release/images/jdk/ test/jdk/javax/security/auth/login/LoginContext
Test results: passed: 9
Report written to /root/jdk/JTreport/html/report.html
Results written to /root/jdk/JTwork

# cat /root/jdk/JTwork/jtData/harness.trace 
# Trace file started at 2022-07-08T07:29:42-0400
# JT Harness version 6.0
# class directory: /root/jdk/jtreg/lib/javatest.jar
# using java: /usr/lib/jvm/java-18-openjdk-18.0.1.0.10-1.rolling.fc36.x86_64
2022-07-08T07:29:42-0400 Starting tests.
Test suite class: com.sun.javatest.regtest.config.RegressionTestSuite
Test finder class: com.sun.javatest.regtest.config.RegressionTestFinder
2022-07-08T07:29:42-0400 Test starting: javax/security/auth/login/LoginContext/ConfigConstructor.java
2022-07-08T07:29:43-0400 Test finished: javax/security/auth/login/LoginContext/ConfigConstructor.java: Passed. Execution successful
2022-07-08T07:29:43-0400 Test starting: javax/security/auth/login/LoginContext/ConfigConstructorNoPerm.java
2022-07-08T07:29:44-0400 Test finished: javax/security/auth/login/LoginContext/ConfigConstructorNoPerm.java: Passed. Execution successful
2022-07-08T07:29:44-0400 Test starting: javax/security/auth/login/LoginContext/DefaultHandler.java
2022-07-08T07:29:45-0400 Test finished: javax/security/auth/login/LoginContext/DefaultHandler.java: Passed. Execution successful
2022-07-08T07:29:45-0400 Test starting: javax/security/auth/login/LoginContext/DynamicConfigurationTest.java
2022-07-08T07:29:47-0400 Test finished: javax/security/auth/login/LoginContext/DynamicConfigurationTest.java: Passed. Execution successful
2022-07-08T07:29:47-0400 Test starting: javax/security/auth/login/LoginContext/LCTest.java
2022-07-08T07:29:49-0400 Test finished: javax/security/auth/login/LoginContext/LCTest.java: Passed. Execution successful
2022-07-08T07:29:49-0400 Test starting: javax/security/auth/login/LoginContext/ModuleSubject.java
2022-07-08T07:29:50-0400 Test finished: javax/security/auth/login/LoginContext/ModuleSubject.java: Passed. Execution successful
2022-07-08T07:29:50-0400 Test starting: javax/security/auth/login/LoginContext/ResetConfigModule.java
2022-07-08T07:29:51-0400 Test finished: javax/security/auth/login/LoginContext/ResetConfigModule.java: Passed. Execution successful
2022-07-08T07:29:51-0400 Test starting: javax/security/auth/login/LoginContext/SharedState.java
2022-07-08T07:29:52-0400 Test finished: javax/security/auth/login/LoginContext/SharedState.java: Passed. Execution successful
2022-07-08T07:29:52-0400 Test starting: javax/security/auth/login/LoginContext/StandardCallbacks.java
2022-07-08T07:29:54-0400 Test finished: javax/security/auth/login/LoginContext/StandardCallbacks.java: Passed. Execution successful
2022-07-08T07:29:54-0400 Doing post-run cleanup
2022-07-08T07:29:54-0400 Completed: All tests passed

@wangweij
Copy link
Contributor

wangweij commented Jul 8, 2022

SmartLoginModule.java is a class used by a test, itself is not one since there's no main() method.

Your new test needs to be a regression test, which means before the fix it fails and after the fix it succeeds. Also, seeing the exception message in a jtreg output with your own eyes is not a test. The test itself should detect the exception and decide whether it's a success or a failure. In the case, I'd recommend you use the System.setErr method to store the output into a ByteArrayOutputStream and then look into it.

@jhuttana
Copy link
Contributor Author

jhuttana commented Jul 8, 2022

SmartLoginModule.java is a class used by a test, itself is not one since there's no main() method.

You are right.

Your new test needs to be a regression test, which means before the fix it fails and after the fix it succeeds. Also, seeing the exception message in a jtreg output with your own eyes is not a test. The test itself should detect the exception and decide whether it's a success or a failure. In the case, I'd recommend you use the System.setErr method to store the output into a ByteArrayOutputStream and then look into it.

Okay! To me at present this looks like a big task to do ;) May be because I haven't written any such tests so far :)
Let me consider this as an opportunity :) I will give a try.

@openjdk openjdk bot removed the rfr Pull request is ready for review label Jul 15, 2022
@openjdk-notifier
Copy link

@jhuttana Please do not rebase or force-push to an active PR as it invalidates existing review comments. All changes will be squashed into a single commit automatically when integrating. See OpenJDK Developers’ Guide for more information.

@jhuttana
Copy link
Contributor Author

jhuttana commented Jul 15, 2022

@wangweij I was trying to add a tets case(I can say its still primary version of the test case. Still there are modifications needed)
First I wanted to make it fit with framework with suitable annotations like @test @compile and @run etc.

At present I am using the example test from here: https://web.mit.edu/java_v1.5.0_22/distrib/share/docs/guide/security/jaas/tutorials/GeneralAcnOnly.html#RunAc
Not sure whether it is recommended or not. Please let me know.

When I am trying the below command, its failing with some exit status which I am unable to find why! :

# jtreg/bin/jtreg -jdk:/root/jdk/build/linux-x86_64-server-release/images/jdk/ -verbose test/jdk/javax/security/auth/login/LoginContext/jaaslogin/
runner starting test: javax/security/auth/login/LoginContext/jaaslogin/sample/SampleAcn.java
runner finished test: javax/security/auth/login/LoginContext/jaaslogin/sample/SampleAcn.java
Failed. Unexpected exit from test [exit code: 255]
Test results: failed: 1
Report written to /root/jdk/JTreport/html/report.html
Results written to /root/jdk/JTwork
Error: Some tests failed or other problems occurred.

I will also investigate further but if you notice something evident could you please let me know whats wrong here?

@wangweij
Copy link
Contributor

There is a .jtr file inside the JTwork directory containing the detail output.

@wangweij
Copy link
Contributor

There are quite some JAAS tests inside test/jdk/javax/security/auth/login where you can copy. The one you found has a very old copyright header and invalid format (like trailing spaces...). Also, I don't think it's worth implementing a new principal and a new login module. You can just using the out-of-box UnixLoginModule and NTLoginModule.

@jhuttana
Copy link
Contributor Author

There are quite some JAAS tests inside test/jdk/javax/security/auth/login where you can copy. The one you found has a very old copyright header and invalid format (like trailing spaces...). Also, I don't think it's worth implementing a new principal and a new login module. You can just using the out-of-box UnixLoginModule and NTLoginModule.

That makes sense :) I will try that.

@wangweij
Copy link
Contributor

wangweij commented Aug 22, 2022

So the patch should look like :
...

Yes. If you decide to print out s no matter if success or not, you can move it out of the if block.

I tried to execute the test case with this change and I don't see anything changed much.

Of course not. It would be useful if the test fails one day. For example, you can try to modify the exception message on line 150 of NTLoginModule and see how the test fails.

}
System.out.printf("-- call stack is -- %n%s%n", s);
Copy link
Contributor

Choose a reason for hiding this comment

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

Print before the exception is thrown.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes

@openjdk openjdk bot added the rfr Pull request is ready for review label Aug 22, 2022
@wangweij
Copy link
Contributor

Please update the copyright line of the test to "Copyright (c) 2022, Red Hat, Inc." since this is a new test. No other comment. Thanks for the patience.

@jhuttana
Copy link
Contributor Author

Please update the copyright line of the test to "Copyright (c) 2022, Red Hat, Inc." since this is a new test. No other comment. Thanks for the patience.

Done :)
In fact I have to thank you a lot for such patience to guide me throughout. Through this one activity I feel I had lot of learning.
Thank you so so much!

@wangweij
Copy link
Contributor

wangweij commented Aug 22, 2022

I've submitted the change to our test servers. Will approve the change once the job is finished.

@jhuttana
Copy link
Contributor Author

I've submitted the change to our test servers. Will approve the change once the job is finished.

Sure thank you!

Copy link
Contributor

@wangweij wangweij left a comment

Choose a reason for hiding this comment

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

Approved.

Some tiny comments (sorry for more):

  1. No need to import Configuration class now.
  2. No need to import Paths class now, or, you can change it to Path and simplify its reference on line 52.

No need for more code review for these changes.

@openjdk
Copy link

openjdk bot commented Aug 22, 2022

@jhuttana This change now passes all automated pre-integration checks.

ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details.

After integration, the commit message for the final commit will be:

8215916: The failure reason of an optional JAAS LoginModule is not logged

Reviewed-by: weijun

You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed.

At the time when this comment was updated there had been 82 new commits pushed to the master branch:

As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details.

As you do not have Committer status in this project an existing Committer must agree to sponsor your change. Possible candidates are the reviewers of this PR (@wangweij) but any other Committer may sponsor as well.

➡️ To flag this PR as ready for integration with the above commit message, type /integrate in a new comment. (Afterwards, your sponsor types /sponsor in a new comment to perform the integration).

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Aug 22, 2022
@jhuttana
Copy link
Contributor Author

Approved.

Some tiny comments (sorry for more):

1. No need to import `Configuration` class now.

2. No need to import `Paths` class now, or, you can change it to `Path` and simplify its reference on line 52.

No need for more code review for these changes.

Done. Thank you!

""";

System.out.println("config is : \n"+config);
Files.writeString(java.nio.file.Path.of("cross-platform"), config.toString());
Copy link
Contributor

Choose a reason for hiding this comment

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

No need to write full package name here then.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Thank you!

@jhuttana
Copy link
Contributor Author

/integrate

@openjdk openjdk bot added the sponsor Pull request is ready to be sponsored label Aug 24, 2022
@openjdk
Copy link

openjdk bot commented Aug 24, 2022

@jhuttana
Your change (at version df47b57) is now ready to be sponsored by a Committer.

@wangweij
Copy link
Contributor

/sponsor

@openjdk
Copy link

openjdk bot commented Aug 24, 2022

Going to push as commit 3c2289d.
Since your change was applied there have been 82 commits pushed to the master branch:

Your commit was automatically rebased without conflicts.

@openjdk openjdk bot added the integrated Pull request has been integrated label Aug 24, 2022
@openjdk openjdk bot closed this Aug 24, 2022
@openjdk openjdk bot removed ready Pull request is ready to be integrated rfr Pull request is ready for review sponsor Pull request is ready to be sponsored labels Aug 24, 2022
@openjdk
Copy link

openjdk bot commented Aug 24, 2022

@wangweij @jhuttana Pushed as commit 3c2289d.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
integrated Pull request has been integrated security security-dev@openjdk.org
Development

Successfully merging this pull request may close these issues.

3 participants