xpipe-io / xpipe

Your entire server infrastructure at your fingertips
https://xpipe.io
Apache License 2.0
3.29k stars 82 forks source link

Potential failure of xpipe to respect $PATH - password managers - dashlane dcli - and password retrieval syntax issues #347

Closed btbutts closed 2 weeks ago

btbutts commented 2 weeks ago

Hello XPipe Devs,

XPipe seems to not always necessarily respect $PATH as defined in MacOS ~/.zprofile. Note that I did install XPipe via homebrew (brew install --cask xpipe-io/tap/xpipe). Moreover, I also installed my Dashlane CLI password manager utility dcli via homebrew (brew install dashlane/tap/dashlane-cli), as well as iTerm2 via (brew install --cask iterm2).

After determining the path for XPipe and DashlaneCLI via: $: which xpipe /usr/local/bin/xpipe $: which dcli /opt/homebrew/bin/dcli

I was able to confirm that both /usr/local/bin & /opt/homebrew/bin are in fact included in $PATH via checking echo $PATH! Furthermore, if I simply run dcli commands from a terminal without sudo, there are no path errors. It works just fine. This should imply that my $PATH variable is setup correctly.

Interestingly, when I view the XPipe settings tab > then "Password manager" and choose Dashlane from the templates drop-down menu, I can leave the default template command syntax dcli password --output console $KEY and enter one of my account key_names to test under the Test password manager section and that works just fine. There are no errors there whatsoever. Therefore, at least for the XPipe app itself, it has no issues calling executables located in $PATH.

However, after saving that default password manager command syntax and then attempting to use the "Password manager" option when defining the account authentication settings for a new Simple SSH Connection, using the appropriate Dashlane account keyname in place of the XPipe variable $KEY_, I receive the following error:

Basic Error

Unable to retrieve password with command dcli password --output console MyAccount-Key_Name

Process returned exit code 127: sh: line 11: dcli: command not found

Error Details

io.xpipe.core.process.ProcessOutputException: Process returned exit code 127: sh: line 11: dcli: command not found at io.xpipe.core.process.ProcessOutputException.of(ProcessOutputException.java:53) at io.xpipe.ext.proc.a.a(SourceFile:330) at io.xpipe.ext.proc.a.readStdoutOrThrow(SourceFile:259) at io.xpipe.app.util.SecretRetrievalStrategy$PasswordManager$1.query(SecretRetrievalStrategy.java:134) at io.xpipe.app.util.SecretQueryProgress.process(SecretQueryProgress.java:129) at io.xpipe.app.beacon.impl.AskpassExchangeImpl.handle(AskpassExchangeImpl.java:33) at io.xpipe.app.beacon.impl.AskpassExchangeImpl.handle(AskpassExchangeImpl.java:11) at io.xpipe.app.beacon.BeaconRequestHandler.handleAuthenticatedRequest(BeaconRequestHandler.java:98) at io.xpipe.app.beacon.BeaconRequestHandler.handle(BeaconRequestHandler.java:66) at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:98) at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:82) at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:101) at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:871) at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:98) at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:847) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) at java.lang.Thread.run(Thread.java:1583)

I receive this error after adding a new Simple SSH Connection and submitting the config so that XPipe can scan the host for services it can connect to. In this situation, no terminal has been started yet, at least not via my chosen emulator iTerm2. That said, after the failure, If I skip it and just try to open an SSH session to the host, I also receive the exact same error above, line for line. Therefore, at a surface level, it would appear as if XPipe's initial SSH session startup script that's launched during each new SSH session is not respecting the user's $PATH, thus the dcli: command not found failure shown above.

Now I can modify the Password manager command syntax so that the full path to dcli is specified (/opt/homebrew/bin/dcli password --output console $KEY) in the XPipe settings, which will remove the command not found errors I described above. However, that's when I noticed another issue...

It would appear that the default Dashlane template is incomplete. Since XPipe expects to receive only one line in response to the password query and no trailing spaces "apparently", I see that you all have configured the --output console option for the dcli password command. Unfortunately, --output console does not replace the default output method (copy to clipboard) in which a message is also displayed in the terminal alerting the user to the fact that their retrieved password is in their clipboard. That message is displayed in addition to the printed password. For example:

/opt/homebrew/bin/dcli password --output console MyAccount-Key_Name MyPassword12345 🔓 password for "MyAccount-Key_Name" copied to clipboard!

Since two lines are provided in response, the response fails. The following errors are returned by XPipe:

Basic Error

Shell opener command was unsuccessful: An error occurred: Received not exactly one output line: MyPassword12345 ���� password for "MyAccount-Key_Name" copied to clipboard!

XPipe requires your password manager command to output only the raw password. If the output includes any formatting, messages, or your password key either matched multiple entries or none, you will have to change the command and/or password key. Permission denied, please try again. Provided secret is wrong

Error Details

io.xpipe.core.process.ProcessOutputException: Shell opener command was unsuccessful: An error occurred: Received not exactly one output line: MyPassword12345 ���� password for "MyAccount-Key_Name" copied to clipboard!

XPipe requires your password manager command to output only the raw password. If the output includes any formatting, messages, or your password key either matched multiple entries or none, you will have to change the command and/or password key. Permission denied, please try again.

Provided secret is wrong

Permission denied, please try again. Provided secret is wrong Received disconnect from 10.1.200.250 port 22:2: Too many authentication failures Disconnected from 10.1.200.250 port 22 at io.xpipe.core.process.ProcessOutputException.withPrefix(ProcessOutputException.java:29) at io.xpipe.ext.proc.util.f.bx(SourceFile:179) at io.xpipe.ext.proc.l.o(SourceFile:2608) at io.xpipe.ext.proc.ssh.r.o(SourceFile:88) at io.xpipe.ext.proc.l.D(SourceFile:509) at io.xpipe.ext.proc.l.start(SourceFile:227) at io.xpipe.app.util.ScanAlert$Dialog.lambda$content$11(ScanAlert.java:208) at io.xpipe.app.util.BooleanScope.executeExclusive(BooleanScope.java:18) at io.xpipe.app.util.ScanAlert$Dialog.lambda$content$12(ScanAlert.java:200) at io.xpipe.app.util.ThreadHelper.lambda$runFailableAsync$1(ThreadHelper.java:42) at io.xpipe.app.util.ThreadHelper.lambda$wrap$0(ThreadHelper.java:19) at java.lang.VirtualThread.run(VirtualThread.java:309)

Because Dashane's dcli tool simply appends the "password in clipboard message" to a new line after the printed password string from the --output console flag, the existing dcli template command flags are insufficient. dcli password --output console $KEY just won't do!

I piped the output of this template to awk to remove all but the first line (the printed password string) via:

/opt/homebrew/bin/dcli password --output console $KEY | awk 'FNR <= 1'

9 times out of 10, piping the default dcli template to awk as shown above resolved the issue and my SSH Connection could now establish using the dcli password manager template (mind you with the full path to dcli defined too). However, I did find that sometimes, I would still get authentication failures when I knew the password was correct. Apparently, XPipe, or some process or something else initialized by XPipe is adding whitespace to the end of passwords. This can be easily reproduced by running the Test password manager in the XPipe settings as there will be at least four spaces after each password returned from the test, regardless of the length. Therefore, I made an additional command modification via:

/opt/homebrew/bin/dcli password --output console $KEY  | awk 'FNR <= 1' | sed 's/\s+$//'

The trailing sed 's/\s+$//' after the second | will remove all traces of whitespace after the password, if any exists. If there is no whitespace after the password, the password is still displayed as-is.

In order for your Dashlane Password manager template to be accurate, and to work, this should be updated, or perhaps documented somewhere. I couldn't find anything on this issue in github or the XPipe Docs so I had to tinker with it until I discovered all of this. I hope all this helps!

Thanks, -Brian

crschnick commented 2 weeks ago

Thank you for your detailed investigation! To answer your questions:

crschnick commented 2 weeks ago

I fixed the output in https://github.com/xpipe-io/xpipe-ptb such that it will discard the second line and remove trailing spaces for dcli

crschnick commented 2 weeks ago

The fix for this is now released in xpipe 12. If it still does not work as expected, feel free to reopen this

btbutts commented 2 weeks ago

Wow that was fast. Thank you! Apparently, I did have that fallback shell enabled. I disabled and restarted XPipe and can confirm that the command not found issue is gone.

I've also upgraded to v12 and removed the | awk 'FNR <= 1' | sed 's/\s+$//' I'd appended to the dcli template. The Dashlane password manager is also working as expected too in v12. Actually, for the first time, when I test a credential $KEY in the XPipe settings, I see the password displayed in the XPipe console v.s. a new shell which looks and works much better.

Thanks again!

crschnick commented 1 week ago

Seems like this has happened a few more times, the sh fallback issue needs some investigation because it shouldn't happen without an underlying problem. Do you use any zsh extensions? I'm just trying to figure out why XPipe thinks your zsh is not functional and falls back to sh.