i3 / i3lock

improved screen locker
https://i3wm.org/i3lock
BSD 3-Clause "New" or "Revised" License
920 stars 404 forks source link

i3lock do unlock without passphrase ! #311

Closed frank-github closed 2 years ago

frank-github commented 2 years ago

I'm submitting a…

[x] Bug [ ] Feature Request [ ] Documentation Request [ ] Other (Please describe in detail)

Current Behavior

i3lock is set up as a systemd unit, which locks the screen before a suspend and only opens it again with a password. This works smoothly when I put the system itself into standby mode.

The system is set to suspend to ram after 15 minutes of inactivity. If the computer is now woken up again from this case, the lock screen is visible, but disappears immediately when any key is pressed.

Problem is reproducable. Problem seems to be option "--no-unlock-indicator ", if this disabled problem seems to be gone.

I did not use i3, I only installed i3lock from debian repository for bullseye

Environment

i3lock: version 2.13 © 2010 Michael Stapelberg

cat /etc/os-release PRETTY_NAME="Debian GNU/Linux 11 (bullseye)" NAME="Debian GNU/Linux" VERSION_ID="11" VERSION="11 (bullseye)" VERSION_CODENAME=bullseye ID=debian

cat /etc/systemd/system/i3lock.service

[Unit] Description=Lock the screen on resume from suspend Before=suspend.target hibernate.target hybrid-sleep.target suspend-then-hibernate.target

[Service] User=dagobert Type=forking Environment=DISPLAY=:0 ExecStart=/usr/bin/i3lock --no-unlock-indicator --ignore-empty-password --image=/screen.png --color=111286

[Install] WantedBy=suspend.target hibernate.target hybrid-sleep.target suspend-then-hibernate.target

stapelberg commented 2 years ago

I can’t reproduce this issue. It works as expected for me.

Can you please:

  1. Check if this still happens when you run i3lock not via systemd, but via xss-lock --transfer-sleep-lock -- i3lock --nofork (you can exec that command from your i3 config file)?
  2. Check that the issue happens without the --image flag, too? Or provide the image file if that’s relevant.
  3. Enable debug logging in i3lock using the --debug flag (beware: logs all key presses, so maybe change your password beforehand) and provide the debug log.
  4. Check the systemd journal for any messages related to i3lock. Did it crash? Can you run coredumpctl debug, then enter backtrace and provide the result?
frank-github commented 2 years ago

HI, thanks for the quick response and help :-)

I found this messages in journalctl i3lock: Cannot grab pointer/keyboard

you can exec that command from your i3 config file

I'm running i3lock as standalone application, I'm not using i3 in total? Do I have a config file? Where is it located? can you give me more information how to use xss-lock, do I start it manually?

I was quit sure I can reproduce it at once, but at the moment I can not reproduce. but I've gotten this problem on and off in the past, I wouldn't have posted here. I can't say for sure, but my problems could be related in time and number to the error messages i3lock: Cannot grab pointer/keyboard Does this message possibly already lead you to the problem?

I am surprised that i3lock just clears the screen lock when it runs into a problem.

below the debug output, maybe it show some details. Interesting side effect during debugging. I entered the correct password the first time, but it was rejected ! On the second try, the debug output shows that I entered the same password identically and now it was accepted.

Feb 24 21:13:25 Latitude i3lock[42823]: [i3lock-debug] device = 3 Feb 24 21:14:45 Latitude i3lock[42823]: [i3lock-debug] Resource Xft.dpi not specified, skipping. Feb 24 21:14:45 Latitude i3lock[42823]: [i3lock-debug] Using fallback for calculating DPI. Feb 24 21:14:45 Latitude i3lock[42823]: [i3lock-debug] Using dpi = 96 Feb 24 21:14:45 Latitude i3lock[42823]: [i3lock-debug] Querying monitors using RandR 1.5 Feb 24 21:14:45 Latitude i3lock[42823]: [i3lock-debug] 1 RandR monitors found (timestamp 17083) Feb 24 21:14:45 Latitude i3lock[42823]: [i3lock-debug] found RandR monitor: 1600 x 900 at 0 x 0 Feb 24 21:14:45 Latitude i3lock[42823]: [i3lock-debug] scaling_factor is 1, physical diameter is 190 px Feb 24 21:14:45 Latitude i3lock[42823]: [i3lock-debug] device = 3 Feb 24 21:14:45 Latitude i3lock[42894]: [i3lock-debug] Watching window 0x04600006 Feb 24 21:14:45 Latitude i3lock[42823]: [i3lock-debug] redraw_screen(unlock_state = 0, auth_state = 0) Feb 24 21:14:45 Latitude i3lock[42823]: [i3lock-debug] allocating pixmap for 1600 x 900 px Feb 24 21:14:45 Latitude i3lock[42823]: [i3lock-debug] scaling_factor is 1, physical diameter is 190 px Feb 24 21:14:50 Latitude i3lock[42895]: [i3lock-debug] process_xkb_event for device 3 Feb 24 21:14:50 Latitude i3lock[42895]: [i3lock-debug] process_xkb_event for device 3 Feb 24 21:14:53 Latitude i3lock[42895]: [i3lock-debug] current password = Feb 24 21:14:56 Latitude i3lock[42895]: [i3lock-debug] current password = i Feb 24 21:14:57 Latitude i3lock[42895]: [i3lock-debug] current password = i3 Feb 24 21:15:00 Latitude i3lock[42895]: [i3lock-debug] current password = i3l Feb 24 21:15:00 Latitude i3lock[42895]: [i3lock-debug] current password = i3lo Feb 24 21:15:00 Latitude i3lock[42895]: [i3lock-debug] current password = i3loc Feb 24 21:15:01 Latitude i3lock[42895]: [i3lock-debug] current password = i3lock Feb 24 21:15:03 Latitude i3lock[42895]: [i3lock-debug] current password = i3lockt Feb 24 21:15:03 Latitude i3lock[42895]: [i3lock-debug] current password = i3lockte Feb 24 21:15:03 Latitude i3lock[42895]: [i3lock-debug] current password = i3locktes Feb 24 21:15:04 Latitude i3lock[42895]: [i3lock-debug] current password = i3locktest Feb 24 21:15:04 Latitude i3lock[42895]: [i3lock-debug] redraw_screen(unlock_state = 1, auth_state = 0) Feb 24 21:15:04 Latitude i3lock[42895]: [i3lock-debug] scaling_factor is 1, physical diameter is 190 px Feb 24 21:15:04 Latitude i3lock[42895]: [i3lock-debug] redraw_screen(unlock_state = 0, auth_state = 1) Feb 24 21:15:04 Latitude i3lock[42895]: [i3lock-debug] scaling_factor is 1, physical diameter is 190 px Feb 24 21:15:04 Latitude i3lock[42895]: pam_unix(i3lock:auth): authentication failure; logname= uid=1000 euid=1000 tty=:0 ruser= rhost= user=frank Feb 24 21:15:07 Latitude i3lock[42895]: Authentication failure Feb 24 21:15:09 Latitude i3lock[42895]: [i3lock-debug] clearing auth wrong Feb 24 21:15:09 Latitude i3lock[42895]: [i3lock-debug] redraw_screen(unlock_state = 0, auth_state = 0) Feb 24 21:15:09 Latitude i3lock[42895]: [i3lock-debug] scaling_factor is 1, physical diameter is 190 px Feb 24 21:15:12 Latitude i3lock[42895]: [i3lock-debug] process_xkb_event for device 3 Feb 24 21:15:12 Latitude i3lock[42895]: [i3lock-debug] process_xkb_event for device 3 Feb 24 21:15:18 Latitude i3lock[42895]: [i3lock-debug] current password = i Feb 24 21:15:18 Latitude i3lock[42895]: [i3lock-debug] current password = i3 Feb 24 21:15:19 Latitude i3lock[42895]: [i3lock-debug] current password = i3l Feb 24 21:15:19 Latitude i3lock[42895]: [i3lock-debug] current password = i3lo Feb 24 21:15:20 Latitude i3lock[42895]: [i3lock-debug] current password = i3loc Feb 24 21:15:20 Latitude i3lock[42895]: [i3lock-debug] current password = i3lock Feb 24 21:15:21 Latitude i3lock[42895]: [i3lock-debug] current password = i3lockt Feb 24 21:15:22 Latitude i3lock[42895]: [i3lock-debug] current password = i3lockte Feb 24 21:15:23 Latitude i3lock[42895]: [i3lock-debug] current password = i3locktes Feb 24 21:15:23 Latitude i3lock[42895]: [i3lock-debug] current password = i3locktest Feb 24 21:15:25 Latitude i3lock[42895]: [i3lock-debug] redraw_screen(unlock_state = 1, auth_state = 0) Feb 24 21:15:25 Latitude i3lock[42895]: [i3lock-debug] scaling_factor is 1, physical diameter is 190 px Feb 24 21:15:25 Latitude i3lock[42895]: [i3lock-debug] redraw_screen(unlock_state = 0, auth_state = 1) Feb 24 21:15:25 Latitude i3lock[42895]: [i3lock-debug] scaling_factor is 1, physical diameter is 190 px Feb 24 21:15:25 Latitude i3lock[42895]: [i3lock-debug] successfully authenticated Feb 24 21:15:25 Latitude i3lock[42895]: [i3lock-debug] restoring focus to X11 window 0x04200006 Feb 24 21:15:25 Latitude i3lock[42894]: [i3lock-debug] Read event of type 18 Feb 24 21:15:25 Latitude i3lock[42894]: [i3lock-debug] UnmapNotify for 0x04600006 Feb 24 21:15:25 Latitude systemd[1]: i3lock.service: Succeeded.

Airblader commented 2 years ago

That error means i3lock isn't able to, well, lock, which it tries a thousand times or so if I remember correctly. There's really no alternative to just giving up at this point—making it look like it's locked when it's not wouldn't be a good idea for obvious reasons.

Is it possible you had a context menu of some sort open when you locked the screen? That's the most common issue that prevents the grab from succeeding.

If you absolutely want to protect against this case, you can wrap i3lock such that a non-zero exit code is followed with an immediate shutdown (or at least logout).

frank-github commented 2 years ago

Is it possible you had a context menu of some sort open when you locked the screen?

I do not think so

In fact, I am not very enthusiastic when my laptop is suddenly openly accessible in case of error Can you give me a description of how to implement your tip? My preference would be to just send the system into a suspend state again.

[addition] Do you mean a simple wrapper script to start i3lock and check his exit code? Do i3lock set an exit code not equal zero in this case of error ?

stapelberg commented 2 years ago

When i3lock prints i3lock: Cannot grab pointer/keyboard, that means locking your screen failed, despite trying hard multiple times and with all counter-measures we know.

You can provoke this state by running echo GETPIN | DISPLAY=:0 pinentry-gtk, which will prevent any screen locker from successfully locking the screen.

There are 2 pieces to the puzzle to integrate i3lock into your environment and prevent suspending without a properly locked screen:

  1. Your environment needs to know when i3lock successfully locked the screen vs. when it had to give up. This is accomplished by using Type=forking with a systemd unit, or with --transfer-sleep-lock when using xss-lock.
  2. Your environment needs to block suspend until i3lock successfully locked.

It’s point 2 that’s the problem in your case.

I was originally going to write that you need to change WantedBy= to RequiredBy= in your systemd unit. I think that’s still correct, but unfortunately even with RequiredBy=, systemd does not seem to block suspend despite i3lock.service not successfully starting.

My recommendation remains to use xss-lock, which uses the inhibit mechanism to integrate with your environment.

But, unfortunately, xss-lock seems to register as an inhibitor in such a way that it only ever delays suspend, not block suspend: https://sources.debian.org/src/xss-lock/0.3.0-10/src/xss-lock.c/?hl=344#L344

You’d need to change delay to block in that line of xss-lock and then run your own version of it, if you really want to circumvent this problem.


Do I have a config file? Where is it located?

No.

can you give me more information how to use xss-lock, do I start it manually?

I’d recommend starting it automatically. I don’t know which desktop environment you use, so I can’t link to more specific instructions. Just start it like you’d start any other program automatically.


Interesting side effect during debugging. I entered the correct password the first time, but it was rejected ! On the second try, the debug output shows that I entered the same password identically and now it was accepted.

No, the password buffer in your logs actually had different contents:

Feb 24 21:14:53 Latitude i3lock[42895]: [i3lock-debug] current password = Feb 24 21:14:56 Latitude i3lock[42895]: [i3lock-debug] current password = i Feb 24 21:14:57 Latitude i3lock[42895]: [i3lock-debug] current password = i3 Feb 24 21:15:00 Latitude i3lock[42895]: [i3lock-debug] current password = i3l

vs.

Feb 24 21:15:18 Latitude i3lock[42895]: [i3lock-debug] current password = i Feb 24 21:15:18 Latitude i3lock[42895]: [i3lock-debug] current password = i3 Feb 24 21:15:19 Latitude i3lock[42895]: [i3lock-debug] current password = i3l

Note that the first buffer has an unprintable character as the first byte.


I don’t know why you only run into this problem when the unlock indicator is disabled. I can reproduce it with or without the unlock indicator when using pinentry to enforce that i3lock can’t grab the screen.

frank-github commented 2 years ago

thanks again for your very helpful informations :-) I will now continue to monitor maybe the idea of the wrapper script will help me in future

I had already read about this on the Internet and my experience so far also confirms this. i3lock is only started by systemd when waking up the system. For a fraction of a second you can see the screen content before i3lock puts the desired image over it.

stapelberg commented 2 years ago

i3lock is only started by systemd when waking up the system

Yeah, this is why I recommend xss-lock. It gets the ordering right (lock screen before suspend) :)

frank-github commented 2 years ago

Ok, you are right, I should switch to xss-lock. I had installed this way to another person long time ago and this one had never problems with i3lock :-)

After I wanted to set up i3lock myself now, I thought systemd is more up to date and so I tried it like this maybe no good idea

frank-github commented 2 years ago

looks like starting over xss-lock is much faster and more secure. Until now I don't get unlocked laptop anymore and lockscreen is set before suspend (seen for a very short moment)

i3lock used as systemd service lockscreen was set after wakeup :-1:

frank-github commented 2 years ago

after some days using i3lock with xss-lock I can confirm i3lock lock screen faster and before suspend. But unfortunately, my original problem is not solved. Every now and then i3lock cannot grab pointer/keyboard and my laptop is not locked

But unfortunately, my original problem is not solved. Every now and then i3lock cannot grab pointer/keyboard and my laptop is not locked :-( I do recognize this now with the help of an i3lock wrapper script, but unfortunately I have not yet found a satisfactory solution on how to deal with the situation. I could of course shut down my laptop in this case, but by doing so I will of course lose my current session An immediate re-suspend is no solution, because i3lock never finds pointer or keyboard in this case.

Airblader commented 2 years ago

You'll need to figure out what is holding the grab when i3lock fails to grab. So the question is what programs are running, and especially which ones are the active / focused ones at that point in time.

frank-github commented 2 years ago

Thanks for the hint, that gives me an idea I must follow the idea and observe it, thank you

stapelberg commented 2 years ago

You can use DISPLAY=:0 xdotool key XF86LogGrabInfo to make X11 print a list of grabs to its log. Maybe you can run that command (automatically) immediately before locking and check the log.

frank-github commented 2 years ago

xdotool I did not know until now

I think I now know the cause, but unfortunately I have too little experience how to work around this. My laptop actually only runs one program in the foreground: Vmware Workstation. In it runs one or two VMs in fullscreen mode and Vmware intercepts all input/mouse etc to direct it to the VMs. Now when I manually put my laptop to sleep, I have previously switched back to my laptop interface and then i3lock works as expected. But if I leave my laptop unplanned a little longer, the "auto suspend" strikes after a certain time. In this case, the lock then does not work because i3lock then can not catch the keyboard / pointer. VMware still has a grip on that to direct the inputs into the VM.

Thanks for the tip with xdotool, this could possibly be the solution. With the key combination CTRL+ALT takes VMWare control back to VM-Host (Laptop) I will put this in my script and test again

stapelberg commented 2 years ago

Ah, you could have mentioned VMware to begin with — yes, it is known to grab input. I don’t know what other VMware users do as workaround, if any. You could try asking on the i3-discuss mailing list, too.

rdiaz02 commented 6 months ago

You can provoke this state by running echo GETPIN | DISPLAY=:0 pinentry-gtk, which will prevent any screen locker from successfully locking the screen.

Minor comment: that is indeed the case with i3lock, xtrlock, and slock. It is also the case with xscreensaver (when using xss-lock -- xscreensaver-command --lock &) though xscreensaver, sometimes, if shortly after resuming you click on the pinentry, for example in the OK, it will then lock.

However, xsecurelock, with option XSECURELOCK_FORCE_GRAB=1 (https://github.com/google/xsecurelock#forcing-grabs) is able to force grab the pointer and thus seems more resistant to this problem (at least in all the testing I've done, both using echo GETPIN | DISPLAY=:0 pinentry-gtk-2 and leaving context menus displayed.

I know this is a closed issue, but I found this issue and its detailed and very helpful discussion (and the very easy to reproduce echo GETPIN | DISPLAY=:0 pinentry-gtk-2), when trying to robustify my screen locking to context menus that were open.