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

openssh-askpass hangs on Manjaro Linux #783

Open
linusdm opened this issue Sep 4, 2022 · 3 comments
Open

openssh-askpass hangs on Manjaro Linux #783

linusdm opened this issue Sep 4, 2022 · 3 comments

Comments

@linusdm
Copy link

linusdm commented Sep 4, 2022

Environment

Current behavior

While trying out nerves on a fresh Manjaro installation (version 21.3.7) I'm unable to run mix burn due to a problem with ask-pass. As documented I have installed the openssh-askpass AUR package, and the askpass binary is available at /usr/bin/qt4-ssh-askpass. Since this is not in the default location (which would be /usr/bin/ssh-askpass) I set the SUDO_ASKPASS environment variable first to point to this location. With this setup the burn command hangs at the point where it should ask for a password (after having confirmed which SD card to burn to).

Output:

$ mix burn
==> nerves
==> sensor_hub

Nerves environment
  MIX_TARGET:   rpi3a
  MIX_ENV:      dev

Use 14.56 GiB memory card found at /dev/sdd? [Yn] 
--- HANGS HERE ---

I use a workaround by installing either the package lxqt-openssh-askpass or x11-ssh-askpass and pointing to the respective binary in SUDO_ASKPASS (/usr/bin/lxqt-openssh-askpass or /usr/lib/ssh/x11-ssh-askpass). This works fine and prompts the root password as expected.

Note that invoking the binary /usr/bin/qt4-ask-password directly works and prompts for a password, but an error is logged:

$ /usr/bin/qt4-ssh-askpass 
ErrorHandler::Throw - warning: QFSFileEngine::open: No file name specified file:  line: 0 function: 

I've heard of someone else having a similar problem on NixOS, although I can't reproduce that exact setup.

This might be just a known issue, but then I would suggest to update the docs to give some more guidance for whoever is in a similar boat.

Also, I'm not sure how to investigate this, as I can't find the exact location where the askpass binary is called. I only see where environment variable is updated, when it's not already set: https://github.com/nerves-project/nerves/blob/main/lib/mix/tasks/burn.ex#L130-L133

Expected behavior

Good integration with the suggested openssh-askpass AUR package for Arch based systems.

@fhunleth
Copy link
Member

fhunleth commented Sep 4, 2022

This might be just a known issue, but then I would suggest to update the docs to give some more guidance for whoever is in a similar boat.

This isn't a known issue to me, so I'm very thankful that you're bringing this up.

The reason that you couldn't find where the askpass binary is called is because it's called by sudo. The SUDO_ASKPASS tells sudo to use the specified program for reading passwords. If sudo doesn't see the environment variable, it will try to read the password itself if it detects an interactive terminal. If not, it fails. Unfortunately, Erlang disassociates child processes from the terminal, so sudo can't read the password the user. That's why the GUI based program is used.

I'll gladly merge whatever updates to the docs you find are needed to make the Nerves tooling work better with Manjaro work.

The ideal solution would be that sudo could ask on the terminal, but I never could figure out how to do that.

@linusdm
Copy link
Author

linusdm commented Sep 11, 2022

Thank you for clarifying, that helped a lot. I didn't know anything about how sudo uses this askpass binary to collect a password.

Tinkering with it some more, I've noticed that the openssh-askpass binary just doesn't work well together with sudo. Simply trying something like SUDO_ASKPASS=/usr/bin/qt4-ssh-askpass sudo -A ls, also hangs, just like it does in the middle of running mix burn. So this is definitely an issue outside of nerves.

I guess I should've read the documentation better, because I just found out there is an explicit reference to an alternative askpass package.

I think you're right that the ideal solution would be to forgo the askpass dependency completely, and let the user fill in a sudo password in the terminal. If the SUDO_ASKPASS variable is not set (I disable these lines in the code), sudo complains like this: sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper.
Do you, or anyone else, have any suggestions on how this would be feasible with the current setup? I see a Port is used (and there is also a code-path that simply uses System.cmd/3) but I'm not sure what the possibilities are to forward keystrokes to sudo when a password is required.

@fhunleth
Copy link
Member

fhunleth commented Sep 11, 2022

This has been a longstanding problem with invoking sudo from Erlang. The best idea that I've had is to create a version of askpass that knows how to interact with a GenServer in the currently running Erlang VM which can get input from the user. I've asked around over the past years if anyone has better ideas. The other alternative was to run posix_spawnp in a NIF, but console I/O formatting was messed up and needed to be adjusted. No one has implemented either of these enough for us to use to my knowledge.

If you're interested in making progress in this area, I think we should start a proof-of-concept project where we can try different ways out and see what works the best. I think that it's doable.

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

No branches or pull requests

2 participants