clevis icon indicating copy to clipboard operation
clevis copied to clipboard

clevis-encrypt-tang is using /dev/tty for input

Open jbaublitz opened this issue 5 years ago • 7 comments

On a somewhat related note to #219, opening /dev/tty as a way to prompt for input makes it very hard to work with clevis in the context of an interactive subprocess. I was attempting to call clevis luks bind as a subprocess but it appeared that clevis was ignoring the standard input I was providing. I used strace and discovered that this line is replacing stdin (which is a pipe connected to the parent process) with the file descriptor from the implicit open("/dev/tty") that results from that bash redirection. The workaround in #219 may be an adequate way around this: require a user to provide the advertisement they wish to use. However, the current way that input is fetched will break any users that are using clevis luks bind in a subprocess with a pipe attached from the parent. Does this seem like a use case you want to avoid? Or is this something you'd consider a valid use case?

jbaublitz avatar Sep 30 '20 16:09 jbaublitz

I think this is irrelevant now that #219 is merged.

jbaublitz avatar Nov 14 '20 14:11 jbaublitz

Hi @jbaublitz , what was the reason for reopening this issue? Is solution provided in #219 not valid?

sarroutbi avatar Jun 09 '21 09:06 sarroutbi

Hi @sarroutbi. Sorry for not providing more context, I thought I had! The problem here essentially boils down to the fact that using /dev/tty here causes unpredictable behavior when doing standard bash redirection like clevis luks bind </dev/null. My expectation here would be that if I ran the above command, Clevis would continue (and fail) if a prompt is accidentally triggered.

The motivation behind this is that I bumped into a case where our daemon that shells out to clevis at one point hit a case where the invocation of clevis caused a hanging prompt. In a daemon, this is a rather large problem and so I wanted to redirect /dev/null to stdin so that if this happened again (which I recognize is really a bug on our end) the user would instead get an error output instead of the daemon hanging. Because you are opening /dev/tty instead of using the process-provided stdin, this redirection will be ignored.

I think my main thought here is that opening /dev/tty will result in atypical behavior with bash redirection. Perhaps this is what you want, but I ended up having to look through the source code to figure out why it was not respecting the /dev/null redirection, and to me that seems like it might confuse other users looking to do similar things.

What are your thoughts?

jbaublitz avatar Jun 09 '21 16:06 jbaublitz

#219 introduced "-y" option so that it is not necessary to confirm when prompted about the keys. Is -y option not valid to avoid hanging prompt?

sarroutbi avatar Jun 09 '21 17:06 sarroutbi

The situation is slightly more complicated than that. I'll refresh myself on the details when I return from time off on Monday and give you more of an in depth answer. Thanks!

jbaublitz avatar Jun 09 '21 17:06 jbaublitz

@sarroutbi Hello! I'm back and here's what it boils down to:

In stratisd, we want to take advantage of the thumbprint checking that Clevis provides. We could theoretically use the -y option always and while we provide an option in our CLI to explicitly trust the URL without checking the thumbprint, ideally we would also like to allow users to verify the thumbprint who are more concerned about security.

While we do provide a guard in our CLI to avoid the condition where Clevis hangs with a prompt using the command line option parser, we don't do this over our D-Bus API given that we simply expect a valid Clevis config as input and pass the Clevis config directly to our clevis luks bind command that we shell out to. If a user does not supply either the thumbprint or the -y option, Clevis will prompt the user in our daemon which understandably is never seen by the user and causes stratisd to hang.

What I'm asking for is for Clevis to use the standard input provided by the command invocation instead of overwriting file descriptor 0 so that we can redirect /dev/null to stdin so that if a user using our API provides neither of these options, Clevis returns immediately with a non-zero exit code even if it does prompt. I don't think that this is too uncommon given that it's standard bash practice to provide </dev/null in these cases. Do you have a particular concern about using the original stdin as opposed to opening /dev/tty? I'm assuming this was an explicit choice on your part so can you provide more context for why you chose this?

jbaublitz avatar Jun 14 '21 15:06 jbaublitz

@sergio-correia This is actually more complicated than initially expected. The reason /dev/tty is there is because the passphrase is expected via stdin. This means that any further bash read calls would fail and cause the script to exit because there is no input left in the piped input. I'm wondering if you'd instead be open to a parameter like --noninteractive that would cause the script to exit with a nonzero code instead of prompting. I would probably achieve this by leaving the /dev/tty prompt the same but just put an exit 1 before that prompt if the flag is set.

jbaublitz avatar Jun 22 '21 22:06 jbaublitz

I think this can be closed because of the linked PR if desired. Coming back to this issue, I think it could be valid to use stdin for both the passphrase and the key trust prompt, but we can avoid this on our end by doing some verification of the config.

jbaublitz avatar May 08 '24 14:05 jbaublitz