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

Add support for fingerprint login #654

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

JAicewizard
Copy link

This is a port of https://github.com/kercre123/ly, hence he is added as co-author.
This PR adds support for fingerprint login, and fixes #227.
I tested this in a single-user setup, by patching this into the arch package. logging in as a non-default user was not tested.

@JAicewizard
Copy link
Author

There turned out to be a couple of issues, one was a fast blinking cursor, which has not been fixed, and one issue where after logging in using fingerprint auth, then logging out, logging back in results in an inability to start sway. I tried reproducing the normal auth flow (not pushed) but nothing really fixes. I might have some time to fix this, but some help would be appreciated!

@JAicewizard
Copy link
Author

I fixed the issue! I also split the normal auth flow in 2, just like the fingerprint auth flow. This removes a lot of duplicate code, and keeps the 2 flows very much similar.

@JAicewizard JAicewizard changed the title Add support for fingerprint login support Add support for fingerprint login Jul 19, 2024
Copy link
Collaborator

@AnErrupTion AnErrupTion left a comment

Choose a reason for hiding this comment

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

The more I look at this PR, the more it looks like just an automatic login feature to me. Unless I missed something, nothing seems to be fingerprint-specific and is just trying to first login at startup (which is fine), but also constantly login afterwards (which is less fine). I believe the latter will burn CPU cycles for not much gain, since the user could simply press Enter after touching their fingerprint reader, or so I assume.

To wrap this up, I have a question: if we were to only apply the changes made to the PAM configuration file, would we be able to still login using a fingerprint reader? I'm not trying to downplay your code additions of course, I'm simply trying to understand if the rest you've added could simply be defined as "convenience features", if you see what I mean.
And, if that's the case, then I think this PR should better be rebranded as adding support for automatic login instead of just fingerprint login.

res/pam.d/ly Outdated Show resolved Hide resolved
src/auth.zig Outdated Show resolved Hide resolved
src/auth.zig Outdated Show resolved Hide resolved
src/main.zig Outdated Show resolved Hide resolved
src/main.zig Outdated
Comment on lines 744 to 752
const shouldFingerprint = switch (event.key) {
termbox.TB_KEY_DELETE => true,
termbox.TB_KEY_BACKSPACE, termbox.TB_KEY_BACKSPACE2 => true,
else => event.ch > 31 and event.ch < 127,
};

if (shouldFingerprint) {
try startFingerPrintLogin(allocator, config, login);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is a bad idea. If anything, it's better to first attempt fingerprint-based login when pressing Enter before attempting to do regular password-based login. But then this wouldn't do much given that the user could simply authenticate normally without a password and it'd do the same thing (at least, as I understand).

Copy link
Author

Choose a reason for hiding this comment

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

This is a bad idea.

Why is this a bad idea? I understand that spawning a lot of threads would be less than ideal, would it be better to do this when the user moved away from the username into the password field? I think I currently like that better than what I implemented now.

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's a bad idea because the user might not expect Ly to try logging in at each keystroke. Probably here, spawning a single thread that'd try logging in using the fingerprint is a better idea.

Copy link
Author

Choose a reason for hiding this comment

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

Yup got it, agree

Copy link
Author

Choose a reason for hiding this comment

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

I dont think we can get all the way there. The problem is that when an authentication is already happening, there is no way to cancel it. So if the user switches username for example, the old auth is still running with no way to cancel it, and thus that thread cannot be used to start a new authentication, and we need to start a new thread. However, I did make it so that it only starts a new authentication when you go to the password field, such that very few threads will be spawned, likely just one. I suspect that only a malicious user would create any significant amount of threads.

src/main.zig Outdated Show resolved Hide resolved
src/main.zig Show resolved Hide resolved
src/main.zig Outdated
try info_line.setText(lang.logout);
}
asyncPamHandle = null;
try startFingerPrintLogin(allocator, config, login);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't understand. Is it trying to authenticate again after logging out?

Copy link
Author

Choose a reason for hiding this comment

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

Yes it is, if someone logged in with their fingerprint, and logged out, they should be able to login with their fingerprint. This might be a problem for something that is permanently plugged into a computer. We could wait for first user-input after logout? This would avoid causing a loop. Optionally we could even make sure the user currently has their cursor on the password field, to allow users to change configuration without being put back into their environment.

Copy link
Collaborator

Choose a reason for hiding this comment

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

But why is it needed in the first place? Can't they just log back in using their fingerprint like they would've done on their first login?

Copy link
Author

Choose a reason for hiding this comment

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

Because we need to start the authentication flow again, after a successful authentication the flow stopped and we need to restart it. But I will first rework this code, maybe its good to look at it again after thatn.

Copy link
Author

Choose a reason for hiding this comment

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

Reworked the code so it looks nicer, and I made is such that on logout it only restarts when entering the password field.

@JAicewizard
Copy link
Author

I'm sorry, github does not seem to be sending me emails about anything anymore, im subscribed to this thread but I just didn't get any emails!! (I even searched all my emails, nothing).

Copy link
Author

@JAicewizard JAicewizard left a comment

Choose a reason for hiding this comment

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

I believe the latter will burn CPU cycles for not much gain, since the user could simply press Enter after touching their fingerprint reader, or so I assume.

This is true, but I think that restarting a PAM login every few minutes is not so bad. We could also increase the timeout to an hour so that there should be basically no wasted cycles (without removing the feature) (https://man.archlinux.org/man/extra/fprintd/pam_fprintd.8.en#timeout=). We are also not doing any expensive computations, the most power-hungry part is probably activating the fingerprint reader, but that is simply the cost of the user enabling it, not something we can do anything about.

To wrap this up, I have a question: if we were to only apply the changes made to the PAM configuration file, would we be able to still login using a fingerprint reader? I'm not trying to downplay your code additions of course, I'm simply trying to understand if the rest you've added could simply be defined as "convenience features", if you see what I mean.

Yes, it would still "work", but without the "convenience features". The idea is that someone should be able to boot their laptop, press the fingerprint-reader, and login, without the user knowing about the PAM hack of filling in an empty password. Users shouldn't have to figure out how to use it, it should "just work".

PS
I have been working on another project in zig with some synchronization primitives, and I think I can clean up the absolute mess that is the timeout code, it is truly horrifying. I don't feel like putting in the effort if you do not want the feature, but if you have the intention of merging this if it gets into a better state I will clean it up.

src/auth.zig Outdated Show resolved Hide resolved
src/auth.zig Outdated Show resolved Hide resolved
src/main.zig Show resolved Hide resolved
src/main.zig Outdated
try info_line.setText(lang.logout);
}
asyncPamHandle = null;
try startFingerPrintLogin(allocator, config, login);
Copy link
Author

Choose a reason for hiding this comment

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

Yes it is, if someone logged in with their fingerprint, and logged out, they should be able to login with their fingerprint. This might be a problem for something that is permanently plugged into a computer. We could wait for first user-input after logout? This would avoid causing a loop. Optionally we could even make sure the user currently has their cursor on the password field, to allow users to change configuration without being put back into their environment.

src/main.zig Outdated Show resolved Hide resolved
src/main.zig Outdated
Comment on lines 744 to 752
const shouldFingerprint = switch (event.key) {
termbox.TB_KEY_DELETE => true,
termbox.TB_KEY_BACKSPACE, termbox.TB_KEY_BACKSPACE2 => true,
else => event.ch > 31 and event.ch < 127,
};

if (shouldFingerprint) {
try startFingerPrintLogin(allocator, config, login);
}
Copy link
Author

Choose a reason for hiding this comment

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

This is a bad idea.

Why is this a bad idea? I understand that spawning a lot of threads would be less than ideal, would it be better to do this when the user moved away from the username into the password field? I think I currently like that better than what I implemented now.

@AnErrupTion
Copy link
Collaborator

@JAicewizard

This is true, but I think that restarting a PAM login every few minutes is not so bad. We could also increase the timeout to an hour so that there should be basically no wasted cycles (without removing the feature)

I'm not a huge fan of adding such a long artificial timeout, plus, with the link you provided, wouldn't this only apply to the pam_fprintd.so module?

We are also not doing any expensive computations, the most power-hungry part is probably activating the fingerprint reader, but that is simply the cost of the user enabling it, not something we can do anything about

Yes, but think about a laptop for example: even if it's not doing anything expensive, if even just one core is pegged at 100%, the fans may spin really fast, which makes you wonder what Ly is even doing in the background... and it's not great.

I don't feel like putting in the effort if you do not want the feature, but if you have the intention of merging this if it gets into a better state I will clean it up.

I do, in fact, want to merge this PR! So if you can improve this PR, then do it! :D

@JAicewizard
Copy link
Author

Yes, but think about a laptop for example: even if it's not doing anything expensive, if even just one core is pegged at 100%, the fans may spin really fast, which makes you wonder what Ly is even doing in the background... and it's not great.

I understand the concern, but while in PAM land the CPU should be idle. pam_fprintd.so offloads to fprintd which waits for a finger to be detected and only then starts to actually perform any computations. This waiting is done using some kind of low-level communication with the reader, fprind shows 0% usage when waiting for a finger for me, I hope that alleviates these concerns.

I do, in fact, want to merge this PR! So if you can improve this PR, then do it! :D

Then I will start working on them when I have time :) I will also do a rebase, just so you know

JAicewizard and others added 4 commits August 20, 2024 17:33
Many thanks to Kerigan for providing the original C code.
This commit mainly posts his code to zig.
Additional features provided by me are:
	- automatically checking every 100ms
	- request new login info for new usernames

Co-authored-by: Kerigan <[email protected]>
This also involves a major split of the authentication code, which allows
the fingerprint and password logins to use the same code.
@JAicewizard JAicewizard force-pushed the fingerprint branch 2 times, most recently from 3e086a3 to a53b904 Compare August 24, 2024 10:35
@JAicewizard
Copy link
Author

I am not sure why github is saying there are merge conflicts, this branch should be fully up-to-date with upstream except one commit which is just about translations, but I think I resolved most issues you pointed out.

@hossamdash
Copy link

@AnErrupTion , would be great if work on this can continue, I can volunteer as tester, I think this will make Ly the best login manager for most linux and specifically wayland users right now.

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.

Support for fingerprint login?
3 participants