profanity-im / profanity

Ncurses based XMPP client
https://profanity-im.github.io/
Other
1.33k stars 188 forks source link

Can't use eval_password #1359

Closed TheBrainScrambler closed 3 years ago

TheBrainScrambler commented 4 years ago

I currently have an user, let's call it . The password of this XMPP user is stored in a KeepassXC database, db.kdbx. I want profanity to get this password through the eval_password setting from the account.

If I do keepassxc-cli show /path/to/db.kdbx /path/to/password -sa Password I am granted with a prompt "Enter your password : " so I type it, and it prints the right password. Everything is ok here.

Now I enter profanity. I do /account set <user> eval_password "keepassxc-cli show /path/to/db.kdbx /path/to/password -sa Password". Ok no problem. But when I /connect, profanity just freezes.

I thought that profanity would spawn a shell where the prompt appears, then you type the password, and then it is good. But no, actually profanity just freezes because the call to keepassxc-cli expects my password, which I have no way to enter.

Expected Behavior

Profanity should give us a way to interact with prompts spawned by eval_password

Current Behavior

Profanity just freezes ...

Possible Solution

As stated above, maybe spawn some temporary shell in the entry field. The user wouldn't see any difference, but he would be typing in that shell.

Steps to Reproduce (for bugs)

  1. Have some KeepassXC file. (should be ending with .kdbx)
  2. For a given user, type /account set <user> eval_password "keepassxc-cli show /path/to/db.kdbx /path/to/password -sa Password
  3. /connect
  4. Enjoy the freeze !

Context

"I want profanity to get this password (the XMPP account's one) through the eval_password setting from the account."

Environment

Build information: XMPP library: libmesode Desktop notification support: Enabled OTR support: Enabled (libotr 4.1.1) PGP support: Enabled (libgpgme 1.13.1) OMEMO support: Enabled C plugins: Enabled Python plugins: Enabled (3.8.3) GTK icons: Enabled



* Operating System/Distribution
Arch Linux
* glib version
Uh ... `pacman -Qs glib`
local/glib2 2.64.2-1
local/glibc 2.31-3

One of the two above I suppose
jubalh commented 4 years ago

I thought that profanity would spawn a shell where the prompt appears, then you type the password, and then it is good. But no, actually profanity just freezes because the call to keepassxc-cli expects my password, which I have no way to enter.

Spawn a shell? Where?

I'm not a keepassxc user, so I don't know what it actually does. Does it open a new X11 window where you enter your password? Does it want to get it from the terminal using stdio?

pass for example uses GPG to encrypt your keys. You can then use various pinentry programs to enter key passphrase. On a headless setup there is pinentry-curses which works nicely with Profanity.

Same method works if you just use GPG to encrypt your keys via eval_password=gpg2 --batch -q --decrypt ~/pw.gpg.

TheBrainScrambler commented 4 years ago

KeepassXC-Cli is taking the entry from the terminal. I don't know if it uses stdio, but you have a prompt in the terminal where you put it.

Spawn a shell? Where?

Where you type your text in profanity. https://profanity-im.github.io/guide/090/basic.html in the input area, "Where commands and messages are entered.". I was thinking about that because keepassxc-cli takes the password from the terminal, as said above. Even if I use something else than keepassxc-cli, I would like to be able to enter my password in the terminal, not having some ncurses interface or some X11 pop-up.

jubalh commented 4 years ago

"takes from terminal" means nothing to me. Neither does "spawn a shell in the input area".

TheBrainScrambler commented 4 years ago

Ok, let me try again. I don't know if you know basic Python, but when I refer to "a prompt in the terminal" or that it is "taking the entry from the terminal" see it like this in Python: password = input("Enter password to unlock {}".format(pathtodb)) If you execute that code, you will get a prompt in your terminal telling you that you should enter your password, and you can type it. This is exactly what keepassxc-cli is doing. Now as for "spawn a shell in the input area" ... Um ... I would say something like typing sh -c $eval_password_cmd in your terminal. It will actually spawn this process in another shell ("spawning a shell") and you will be able to enter the password, then it will output the password to the standard output. So "spawning a shell in the input area" would be this but, instead of doing this in the terminal, you do that in Profanity's input area

PS: Just've understood what you meant by stdio now, yes that's where keepassxc-cli takes the password from.

wstrm commented 4 years ago

I think I'm going to just test this and see if I'm also getting a freeze!

jubalh commented 4 years ago

I think you will. AFAIK we just open a process to get the password. We don't send anything to it. In case of pineentry the receiving is not done by Profanity but pineentry. So we don't anything to the process we call over stdio.

wstrm commented 4 years ago

Hm yeah, I also get a freeze, would be nice if one could enter the password in the same terminal. When I use pass it simply gets the output directly as gpg has remembered my password.

It would be nice if the command also gets control like when using system() in stdlib.h. mutt has this, so when I start it I get: 2020-07-01-173850_739x231_scrot And mutt gets the output from the program and uses as a password. Not sure how they've implemented it and maybe there are some security implications.

(one can force console Pinentry when using gpg with: export GPG_TTY=$(tty))

jubalh commented 4 years ago

But that screenshot is just pinentry-curses, isn't it? Profanity does the same if you use that. Without a freeze AFAIK.

wstrm commented 4 years ago

Ah, sorry, bad example as Pinentry takes over the TTY. mutt allow me to issue the keepassxc-cli command - so they do something different than Profanity.

Anyhooooow... I made a small script that solves this by calling Pinentry and passing the password to keepassxc-cli:

#!/usr/bin/env bash

db=$1
path=$2

pinentry-curses --ttyname "$(tty)" <<EOF \
    | grep D \
    | cut -d' ' -f2 \
    | keepassxc-cli show "${db}" "${path}" --quiet -sa Password
SETPROMPT Master Password:
GETPIN
EOF

Put this in a file somewhere, like /usr/local/bin/keepassxc-pinentry, chmod +x it, and use it like:

keepassxc-pinentry <db> <path>

I've tested it with Profanity, with eval_password set as:

eval_password=/usr/local/bin/keepassxc-pinentry <db> <path>

@TheBrainScrambler does this work for you? :)

TheBrainScrambler commented 4 years ago

@wstrm Well strangely ... no. I'm getting Error evaluating password, see logs for details. in profanity and prof: ERR: Calling 'keepassxc-pinentry' failed: Child process exited with code 1. in the errors ...

What I did: I created keepassxc-pinentry in my home and made it executable. When launching it with ./keepassxc-pinentry it perfectly works. Also works by executing it with the full path. (like /home/user/keepassxc-pinentry. Now I launch profanity PATH=~:$PATH profanity And set the settings /account set <name> eval_password keepassxc-pinentry Doesn't work. I've also tried /account set <name> eval_password /home/user/keepassxc-pinentry instead, same result. Profanity perfectly finds the script and it able to execute it, however it fails to execute it correctly for an unknown reason ...

wstrm commented 4 years ago

Have you passed <db> <path>, in the end, too? Like:

/account set <name> eval_password /home/user/keepassxc-pinentry <db> <path>
TheBrainScrambler commented 4 years ago

Oh, no, forgot to mention that I directly hardcoded those in the script. And it perfectly works if I run it, as said above: it prints me the right password to stdout. The problem must be elsewhere.

wstrm commented 4 years ago

Is it possible that you run Profanity as another user? Or maybe you have some exotic setup, maybe you could tell me how you run Profanity?

I get the same error when the owner of the TTY is different than the current user that is running the script.

~ $ whoami
user1
~ $ ls -l $(tty)
crw--w---- 1 user2 tty 136, 12 Jul  4 11:19 /dev/pts/12
TheBrainScrambler commented 4 years ago
$ whoami
user1
$ ls -l (tty)
crw--w---- 1 user1 tty somedatestuffhere /dev/pts/0

I don't have any particular setup, I'm just using Gnome DE with gnome-terminal on Arch Linux

wstrm commented 4 years ago

OK so I think this is the fault of some recent commit.

This works when running Profanity 0.8.1, but I get the same error as you on 0.9.5. What version of Profanity are you running @TheBrainScrambler?

jubalh commented 4 years ago

call_external() was changed recently.

https://github.com/profanity-im/profanity/commit/fad77d9d70b405d307c85ced27796c052ace050d https://github.com/profanity-im/profanity/commit/d92c576aa53505d712715b1acc6344af3262c84f

TheBrainScrambler commented 4 years ago

I am currently using the 0.9.2 version

jubalh commented 3 years ago

@wstrm ping

wstrm commented 3 years ago

Did #1459 fix this?

jubalh commented 3 years ago

Most likely works ;)