akinomyoga / ble.sh

Bash Line Editor―a line editor written in pure Bash with syntax highlighting, auto suggestions, vim modes, etc. for Bash interactive sessions.
BSD 3-Clause "New" or "Revised" License
2.72k stars 86 forks source link

[Solus ufw] completion breaks on commands not executable by non-root #496

Closed solomongrundy6 closed 2 months ago

solomongrundy6 commented 2 months ago

ble version: 0.4.0-nightly+75c4a84 Bash version:

5.2.32(1)-release (x86_64-solus-linux-gnu)

I forgot that ufw needs sudo to run, and was typing in ufw status and I got a bunch of this:

ufw sbash: /usr/sbin/ufw: Permission denied
stbash: /usr/sbin/ufw: Permission denied
bash: /usr/sbin/ufw: Permission denied
tabash: /usr/sbin/ufw: Permission denied
bash: /usr/sbin/ufw: Permission denied
bash: /usr/sbin/ufw: Permission denied
bash: /usr/sbin/ufw: Permission denied
atbash: /usr/sbin/ufw: Permission denied
bash: /usr/sbin/ufw: Permission denied
bash: /usr/sbin/ufw: Permission denied
bash: /usr/sbin/ufw: Permission denied

I think the problem is that on my system, ufw is installed with these permissions: -rwxr--r-- 1 root root 4972 Feb 25 2024 /usr/sbin/ufw so that when blesh tries to get a --help or whatever to populate the possible completion suggestions, it fails all over the place, because it has no executable bit set for non-root. Ideally it would just fail silently instead and not give any completion suggestions for that particular command. If I prepend sudo and type sudo ufw status instead, it does not fail on suggestions but will behave the same way upon pressing TAB for completion:

sudo ufw statbash: /usr/sbin/ufw: Permission denied
bash: /usr/sbin/ufw: Permission denied
bash: /usr/sbin/ufw: Permission denied
bash: /usr/sbin/ufw: Permission denied

Love the script otherwise, have had no other problems yet.

akinomyoga commented 2 months ago

Thanks for the report. This is related to the auto-complete feature of ble.sh, where ble.sh calls the programmable completion setting for the ufw command. ble.sh itself doesn't provide the completion setting for the ufw command, but the completion setting should be provided externally.

so that when blesh tries to get a --help or whatever to populate the possible completion suggestions,

edit: Although the command may be executed by a completion setting that ble.sh calls, ble.sh itself never executes the command to try to get the completions because ble.sh doesn't know if it is safe to execute the command because not all the commands support --help. ble.sh only checks the man page to try to extract the options that the command supports.

I suspect the same problem happens even without ble.sh when you attempt a TAB completion in the plain Bash plus the completion setting for ufw.

$ complete -p ufw
$ ufw stat[TAB]
akinomyoga commented 2 months ago
$ (shopt -s extdebug; declare -F <function_name>)
$ type <function_name>

Please replace <function_name> with the actual string found in the output of the command in Q1. It would typically be something like _ufw or _comp_cmd_ufw, though it might have a totally different name.

akinomyoga commented 2 months ago

There seem to be independent implementations of the completion setting of the ufw command:

The first one attempts to execute ufw only for ufw info and ufw update, so it is probably different from your setting. The second one seems to attempt to execute ufw to complete the first word, so this may be the completion setting in your system. I'm not sure whether there are even other implementations of the completion setting of the ufw command. I still want the answers to Q1...Q3 above.

Even if the command is intended to be run through sudo, the completion setting is expected to be run in the user's shell (through the completion setting of the sudo command). This means that the above completion settings do not assume the case where the ufw binary is marked as non-executable for non-root users. I'm not sure if it is related, but the following report contains an example where the TAB completion is attempted without sudo and no permission errors are discussed:

I think this also suggests that the permission in your system is not a typical one, and the completion setting doesn't support such a case.

akinomyoga commented 2 months ago

Your MACHTYPE x86_64-solus-linux-gnu implies you use Solus. Is that correct? I tried to search a package in the Solus repository: I can find information on pkgs.org:

Also, there seems to be a GitHub repository that maintains the packages in Solus. The following tree is related to the ufw package in Solus:

This line sets the permission of /usr/sbin/ufw to 00744. I think either the permission of /usr/sbin/ufw or the completion setting needs to be patched.

You reported that the problem doesn't arise when sudo is prefixed. Regarding this behavior, I have another question.

$ ble/widget/display-shell-version

I'm also looking forward to seeing the answers to Q1...Q3. Thank you.

solomongrundy6 commented 2 months ago

Yes, I'm using Solus 4.5 (up to date as of today)

Q1 (complete -p ufw) bash: complete: ufw: no completion specification

Q2 (ufw statTAB without blesh) This works as expected, no errors.

Q3 N/A per results of Q1

Q4

GNU bash, version 5.2.32(1)-release (x86_64-solus-linux-gnu) [Solus 4.5 Resilience]
ble.sh, version 0.4.0-nightly+75c4a84 (noarch) [git 2.46.0, GNU Make 4.3, GNU Awk 5.1.0, API: 3.0 (GNU MPFR 4.1.0, GNU MP 6.2.1)]
bash-completion, version 2.11 (hash:1a7f5634b4c9816716b69a7824e0b51cfde2bca3, 76332 bytes) (noarch)
locale: LANG=en_US.UTF-8
terminal: TERM=xterm-kitty wcwidth=15.0-west/15.1-2+ri, kitty:0 (1;4000;36)

If ufw's permissions do need to be patched I can pass that along in an issue to Solus.

solomongrundy6 commented 2 months ago

Also, as an experiment I changed the permissions on ufw to rwxr-xr-x and completion behaved normally, changing it back to what it was before the error comes back. I probably should file an issue with Solus - ufw seems to be the only file in /usr/sbin without executable permissions set for non-root users so it may very well be a packaging oversight.

akinomyoga commented 2 months ago

Thank you for the answers. Hmm, if the error message doesn't happen with Q2, the problem may not be the fault of the Solus package of the ufw command.

However, the situation is somewhat strange. As far as I see the setup in the package information, the completion setting should be loaded by an attempt of the TAB completion, but the answer to Q1 reports nothing. In addition, Q2 also doesn't load anything. Even though, the answer to Q4 tells that bash-completion is loaded.

$ ls -l /usr/share/bash-completion/completions/ufw

edit: Sorry, I fixed the above command from ls -l /usr/share/bash-completion/ufw to ls -l /usr/share/bash-completion/completions/ufw.

Hmm, just to confirm,

solomongrundy6 commented 2 months ago

Q1a: Sorry, no, I didn't see that I was supposed to do that after the error message. The amended result is:

$ complete -p ufw
complete -F _ufw ufw
$ (shopt -s extdebug; declare -F _ufw)
_ufw 61 /usr/share//bash-completion/completions/ufw
$ type _ufw
_ufw is a function
_ufw () 
{ 
    cur=${COMP_WORDS[COMP_CWORD]};
    prev=${COMP_WORDS[COMP_CWORD-1]};
    if [ $COMP_CWORD -eq 1 ]; then
        COMPREPLY=($(compgen -W "--dry-run --force --help $(_ufw_commands)" -- $cur));
    else
        if [ $COMP_CWORD -eq 2 ]; then
            case "$prev" in 
                app)
                    COMPREPLY=($(compgen -W "$(_ufw_app_commands)" -- $cur))
                ;;
                status)
                    COMPREPLY=($(compgen -W "$(_ufw_status_commands)" -- $cur))
                ;;
                delete)
                    COMPREPLY=($(compgen -W "$(_ufw_rule_commands)" -- $cur))
                ;;
                route)
                    COMPREPLY=($(compgen -W "$(_ufw_route_commands)" -- $cur))
                ;;
                logging)
                    COMPREPLY=($(compgen -W "$(_ufw_logging_commands)" -- $cur))
                ;;
                show)
                    COMPREPLY=($(compgen -W "$(_ufw_show_commands)" -- $cur))
                ;;
                default)
                    COMPREPLY=($(compgen -W "$(_ufw_default_commands)" -- $cur))
                ;;
            esac;
        fi;
    fi
}
akinomyoga commented 2 months ago

Thank you! Then the next mystery is the reason why you don't see the error message in Q2. As far as I understand, the same error should happen also with the TAB completion without ble.sh. Maybe the way how I asked the question was bad.

solomongrundy6 commented 2 months ago

Q2a: Running without blesh (but with normal distro-supplied bash completion sourced) it seems to work fine. Though this is effectively the same way I ran it before in Q2.

akinomyoga commented 2 months ago

Thank you. Hmm, maybe the setup could be different from what I assume.

$ complete -p -D
$ # after attempting a TAB completion of "ufw ...[TAB]"
$ complete -p ufw
solomongrundy6 commented 2 months ago

My bad, the error does occur. I was changing to another user to run bash without my bashrc/profile at first. But the user I switched to was root, so of course it worked, root owns that binary. You're right, the error does occur without it:

$ bash --noprofile --norc
bash-5.2$ source /usr/share/bash-completion/bash_completion 
bash-5.2$ ufw sbash: /usr/sbin/ufw: Permission denied
bash: /usr/sbin/ufw: Permission denied
bash-5.2$ 
akinomyoga commented 2 months ago

Ah, OK! Then the mystery was solved! As I suspected, the completion setting of ufw will always fail with the specific setup of the ufw package in Solus. Thank you for the confirmation!

solomongrundy6 commented 2 months ago

No problem. I'll amend the solus issue too.

akinomyoga commented 2 months ago

Thank you!

akinomyoga commented 2 months ago

@solomongrundy6 As a temporary workaround, you can put the following lines in ~/.bashrc (somewhere after loading both bash-completion and ble.sh).

# bashrc

__load_completion ufw
ble/function#suppress-stderr _ufw
solomongrundy6 commented 2 months ago

Fixed by #3741

akinomyoga commented 2 months ago

Thank you!