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

pam: Use pam.ModuleTransaction to implement pam module #89

Merged
merged 12 commits into from
Nov 30, 2023

Conversation

3v1n0
Copy link
Collaborator

@3v1n0 3v1n0 commented Oct 14, 2023

Re-implement the PAM module bootstrap code by using pam-go and in particular the code proposed at msteinert/pam#13

That allows us to have a more tested and testable base. Also it will be a prerequisite for the gdm implementation and a pure-PAM protocol implementation.

The module can now generated by just using go generate -C pam that would generate in two steps both the go-glue code and the library itself.

See single commits for further details.

UDENG-1647, UDENG-1604

@3v1n0 3v1n0 requested a review from a team as a code owner October 14, 2023 05:09
@3v1n0 3v1n0 force-pushed the use-pam-moduler branch 4 times, most recently from 87f38eb to 0435964 Compare October 14, 2023 05:31
Copy link
Member

@denisonbarbosa denisonbarbosa left a comment

Choose a reason for hiding this comment

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

Hey @3v1n0! I tried to explain as much as possible the reasons behind the changes related to idiomatic Go, so I hope everything is clear. I'm not an expert on PAM behavior, so if I missed or misunderstood something, feel free to let me know in the comments.

I'm still a bit unsure about switching what we already implemented ourselves to an external dependency (as it pulls a lot of weight that I'm not sure we need), but we can discuss it.

pam/pam-module-transaction-dummy.go Outdated Show resolved Hide resolved
pam/pam-module-transaction-dummy.go Outdated Show resolved Hide resolved
pam/pam-module-transaction-dummy.go Outdated Show resolved Hide resolved
pam/pam-module-transaction-dummy.go Outdated Show resolved Hide resolved
pam/pam-module-transaction-dummy.go Outdated Show resolved Hide resolved
pam/pam-module-transaction-dummy.go Outdated Show resolved Hide resolved
pam/pam-module-transaction-dummy.go Outdated Show resolved Hide resolved
pam/pam-module-transaction-dummy.go Outdated Show resolved Hide resolved
pam/pam-module-transaction-dummy.go Outdated Show resolved Hide resolved
pam/pam-module-transaction-dummy_test.go Outdated Show resolved Hide resolved
@3v1n0 3v1n0 force-pushed the use-pam-moduler branch 2 times, most recently from e6d13b2 to 0d94233 Compare October 17, 2023 18:23
@3v1n0
Copy link
Collaborator Author

3v1n0 commented Oct 17, 2023

Hey @3v1n0! I tried to explain as much as possible the reasons behind the changes related to idiomatic Go, so I hope everything is clear. I'm not an expert on PAM behavior, so if I missed or misunderstood something, feel free to let me know in the comments.

Thanks, I'm still attached to some C-isms, so happy to learn! :)

I'm still a bit unsure about switching what we already implemented ourselves to an external dependency (as it pulls a lot of weight that I'm not sure we need), but we can discuss it.

So, what we had implemented so far was just a tiny bit of what we actually need to perform everything we care about (some of the wip code is stashed here), but the current code needed still various C implementations and was very hard to test, so I decided that:

  • Separation of concern, there's a go-pam library that had already various things we needed and a nice abstraction and it was way better to improve things there instead of having everything inside authd
  • Working in go-pam externelly allowed me to test things fully, so now basically any interaction of go-pam with actual libpam is tested in both ways (i.e. the generator and the modules are creating code on the go and the built libraries loaded via libpam to be tested) in behaviors and memory.
  • All these abstractions that we now have allow to easily create mocks and testable pam.ModuleTransaction's that we can now re-implement in various way depending on the test we want to do:
    • This also includes the possibility (I hope remote) to make this a wrapper to call the libraries in different ways if shared libraries create troubles to PAM.
  • Avoid touching C as much as we can inside this repo

So basically my goal was to have a library that allowed us to do everything we need, especially in the GDM and pure-PAM (e.g. ssh) modes without having to care how the low-level implementation is done, assuming that is fully tested.

Copy link
Contributor

@GabrielNagy GabrielNagy left a comment

Choose a reason for hiding this comment

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

Awesome work! My comments are all related to testing :)

pam/pam_test/pam-module-transaction-dummy_test.go Outdated Show resolved Hide resolved
pam/pam_test/pam-module-transaction-dummy_test.go Outdated Show resolved Hide resolved
pam/authentication.go Show resolved Hide resolved
Copy link
Member

@denisonbarbosa denisonbarbosa left a comment

Choose a reason for hiding this comment

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

Hey @3v1n0, thanks for addressing the comments and for explaining some others in which I misunderstood the purpose of the changes. I have another request and, even though it's a single comment, it's a big (and also very important) one. If you're unsure how to move on with the table-testing approach, we can talk more about it in the specific comment, MM or HO.

Also, please avoid resolving the comments yourself, if possible. The comments are very useful for the reviewer to navigate through what was requested and to see if they were addressed or not. What we do normally is for the PR author to react with a 👍 on the comment if it was addressed or to discuss the change a bit more on the comment itself before deciding how (and if) to address it. After everything is addressed and discussed, you can re-request the review so the reviewer can take another look at the changes. Here's a short PR as an example: #58.

pam/pam_test/pam-module-transaction-dummy_test.go Outdated Show resolved Hide resolved
@3v1n0 3v1n0 force-pushed the use-pam-moduler branch 2 times, most recently from 7775d8d to f95e0b8 Compare October 20, 2023 01:05
Copy link
Member

@denisonbarbosa denisonbarbosa left a comment

Choose a reason for hiding this comment

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

Hey @3v1n0, I appreciate you taking the time to address the comments and discuss them. Thanks!
We are not quite there yet, though. I feel like the table tests can be improved quite a bit, as right now they are a bit confusing and hard to read. I wrote more details in the specific comment. Hopefully, it's clearer.

pam/pam_test/module-transaction-dummy_test.go Outdated Show resolved Hide resolved
@3v1n0 3v1n0 force-pushed the use-pam-moduler branch 5 times, most recently from b6f3d32 to 4f6ea76 Compare October 25, 2023 23:48
@3v1n0 3v1n0 force-pushed the use-pam-moduler branch 2 times, most recently from eba2215 to 1a24037 Compare October 26, 2023 02:38
Copy link
Member

@denisonbarbosa denisonbarbosa left a comment

Choose a reason for hiding this comment

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

Hey @3v1n0. Well done! I definitely like the tests a lot more now.
I still think there's more room for improvement though, so I added some final comments and suggestions to improve readability and consistency.

(The nitpicks are also to prepare you for @didrocks review 😂 ...)

pam/pam_test/module-transaction-dummy_test.go Outdated Show resolved Hide resolved
pam/pam_test/module-transaction-dummy_test.go Outdated Show resolved Hide resolved
pam/pam_test/module-transaction-dummy_test.go Outdated Show resolved Hide resolved
pam/pam_test/module-transaction-dummy_test.go Outdated Show resolved Hide resolved
pam/pam_test/module-transaction-dummy_test.go Outdated Show resolved Hide resolved
pam/pam_test/module-transaction-dummy_test.go Outdated Show resolved Hide resolved
pam/pam_test/module-transaction-dummy_test.go Outdated Show resolved Hide resolved
pam/pam_test/module-transaction-dummy_test.go Outdated Show resolved Hide resolved
pam/pam_test/module-transaction-dummy_test.go Outdated Show resolved Hide resolved
pam/pam_test/module-transaction-dummy_test.go Outdated Show resolved Hide resolved
@3v1n0
Copy link
Collaborator Author

3v1n0 commented Nov 28, 2023

Still some things to improve (besides Didier's comments). It would be really helpful if you avoid rebasing the pull request on every change

I rebase on the same base all the times, since that's the way everywhere else things happen, but let me know if you prefer me to push fixup: commits instead.

@3v1n0
Copy link
Collaborator Author

3v1n0 commented Nov 28, 2023

rebase

Also normally in such cases the way to do is to do is use the Compare link there, to see the changes that happened in between.

And since I'm not never rebasing against a newer main, it should not include any clutter.
But if you prefer fixup!'s I'll do them.

immagine

@denisonbarbosa
Copy link
Member

Also normally in such cases the way to do is to do is use the Compare link there, to see the changes that happened in between.

The issue with the compare link is that it only compares the heads, which means we won't see any diff before them, that's why going with fixups is better.

@3v1n0
Copy link
Collaborator Author

3v1n0 commented Nov 28, 2023

Also normally in such cases the way to do is to do is use the Compare link there, to see the changes that happened in between.

The issue with the compare link is that it only compares the heads, which means we won't see any diff before them, that's why going with fixups is better.

You can manually provide the sha from your previous review, but no worries... I'll go with fixups.

pam/return.go Outdated Show resolved Hide resolved
@3v1n0
Copy link
Collaborator Author

3v1n0 commented Nov 29, 2023

So... I've finally got some upstream reviews on msteinert/pam#15 and so I also updated the branch here, this also implied renaming pam.StatusError -> pam.Error and dropping for good pam.TransactionError and rely on error wrapping everywhere.

Changes are in the fixups and are quite minimal at the end.

@didrocks
Copy link
Member

So... I've finally got some upstream reviews on msteinert/pam#15 and so I also updated the branch here, this also implied renaming pam.StatusError -> pam.Error and dropping for good pam.TransactionError and rely on error wrapping everywhere.

See, we are not that foreign or make unreasonable requests ;)

Copy link
Member

@denisonbarbosa denisonbarbosa left a comment

Choose a reason for hiding this comment

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

Ok, I think we are done now, @3v1n0. Great job! 🚀

If @didrocks has nothing more to say as well, feel free to rebase the branch on the latest changes on main and join the fixups so we can get this merged!

@didrocks didrocks removed their request for review November 30, 2023 16:33
@didrocks didrocks dismissed their stale review November 30, 2023 16:34

Trusting the other reviews and no time to rereview myself.

Avoid doing all the C manual work inside authd pam, but handle this in a
separate library that handles this all and comes with fully tested
operations.

We could so mock the ModuleTransaction here if we want so that we can
make things more testable as they are now.

As per this change, the module can be simply be generated with:

  go generate -C pam
Instead of using our own types for return status, let's just use
pam.StatusError to return more complex error values back to the
user
We used to store the authentication ID as global value, but pam can
handle this natively now, allowing us to store it as module data.
We have a base interface that the pam.ModuleTransaction should implement
and so use and pass this interface instead of relying on the actual
module transaction implementation, so that we can mock it.

As per this introduce a new dummy implementation for it that can be used
in local tests
As per this, do not define main() as an actual function when we're
generating the module, to avoid adding unwanted code in the library.
PAM code is using CGO quite a lot, so run tests using address sanitizer
to catch memory issues and leaks
ASAN in go does not catch memory leaks properly at the end of the
test program execution, so force this using a wrapper function that is
called when each test is completed.
@denisonbarbosa denisonbarbosa merged commit 9151507 into ubuntu:main Nov 30, 2023
4 checks passed
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.

6 participants