microsoft / Git-Credential-Manager-for-Mac-and-Linux

Git Credential Manager for Mac and Linux stores credentials for Git version control securely. Provides secure logon for Visual Studio Team Services (visualstudio.com).
Other
406 stars 240 forks source link

Wrong home path is set, unable to use with sudo #97

Open martinhartmann opened 6 years ago

martinhartmann commented 6 years ago

Description

OS: Ubuntu Server 16.04.5

I'm trying to use it in combination with etckeeper.

I always get the error

Fatal: java.lang.RuntimeException encountered.  Details:
Secure credential storage is not available on this operating system. You may opt-in to store credentials in an unencrypted file under your user home directory by running 'git config --global credential.canFallBackToInsecureStore true'.

when pushing with sudo.

sudo git config --global credential.canFallBackToInsecureStore true

sets the directive in /home/user/.gitconfig, but not /root/.gitconfig where the credential manager reads the config from. Event a prompt for user and password isn't shown, probably because the fallback entry is not set.

Suggestion

Follow git configs way of parsing $HOME/.gitconfig instead of real users Java's user.home. At least for Linux, I don't have any Mac here to test this, but I think it behaves exactly the same.

Workaround

I currently added

-Duser.home=$HOME

to credential.helper in .gitconfig as it's working as intended.

Tracing the error

I run this tool under Ubuntu Server which has a sudo-only approach and sudoing preserves $HOME.

git pushing via a regular user parses the /home/user/.gitconfig file, which I can see in the output with -Ddebug=true.

sudo git pushing does not parse /home/user/.gitconfig but instead /root/.gitconfig where the credential helper config directives are not present, of course, and also ~/.VSTeamServicesAuthPlugin/insecureStore.xml is missing when using the fallback.

I'm not familiar very with Java, but printing

Environment.getFolderPath(Environment.SpecialFolder.UserProfile)

in

Where.gitGlobalConfig()

outputs /root as expected. As I see in com.microsoft.alm.helpers.Environment.getFolderPath()

SpecialFolder.UserProfile

returns

System.getProperty("user.home")

According to this Stack Overflow Thread it's

probably still the best

but

System.getenv( "HOME" )

is not a wrong way to resolve the home directory for a user. Obviously git config does it this way but I didn't look in the source.

Logs:

Pushing in /etc with root using default config -Ddebug=false:

19:19:12 root common-vm master /etc
 # git push --set-upstream my.domain.tld master
Fatal: java.lang.RuntimeException encountered.  Details:
Secure credential storage is not available on this operating system. You may opt-in to store credentials in an unencrypted file under your user home directory by running 'git config --global credential.canFallBackToInsecureStore true'.
fatal: credential helper '!/home/linuxbrew/.linuxbrew/Cellar/jdk/9.0.4/bin/java -Ddebug=false -Djava.net.useSystemProxies=true -jar /home/linuxbrew/.linuxbrew/Cellar/git-credential-manager/2.0.4/libexec/git-credential-manager-2.0.4.jar' told us to quit

Same push using -Ddebug=true:

19:20:07 root common-vm master /etc
 # git push --set-upstream my.domain.tld master
Configuration::loadGitConfiguration
Configuration::ParseGitConfig
Configuration::ParseGitConfig
   branch.master.merge = refs/heads/master
   branch.master.remote = my.domain.tld
   core.bare = false
   core.filemode = true
   core.logallrefupdates = true
   core.repositoryformatversion = 0
   remote.my.domain.tld.fetch = +refs/heads/*:refs/remotes/my.domain.tld/*
   remote.my.domain.tld.url = https://my.domain.tld/my.domain.tld/common-vm-configuration.git
   user.name = root
Program::loadOperationArguments
Configuration::tryGetEntry
Configuration::tryGetEntry
Configuration::tryGetEntry
Configuration::tryGetEntry
Configuration::tryGetEntry
Configuration::tryGetEntry
Program::EnableTraceLogging
Program::get
   targetUri = https://my.domain.tld/
Program::ComponentFactory::createSecureStore
gnome-keyring library not loadedjava.lang.UnsatisfiedLinkError: Unable to load library 'gnome-keyring': Native library (linux-x86-64/libgnome-keyring.so) not found in resource path (/home/linuxbrew/.linuxbrew/Cellar/git-credential-manager/2.0.4/libexec/git-credential-manager-2.0.4.jar)
gnome-keyring library not loadedjava.lang.NoClassDefFoundError: Could not initialize class com.microsoft.alm.storage.posix.internal.GnomeKeyringLibrary
gnome-keyring library not loaded, return null for SCHEMA
Getting a persistent token store that must be secure
Fatal error encountered.  Details:
java.lang.RuntimeException: Secure credential storage is not available on this operating system. You may opt-in to store credentials in an unencrypted file under your user home directory by running 'git config --global credential.canFallBackToInsecureStore true'.
        at com.microsoft.alm.gitcredentialmanager.Program$ComponentFactory.createSecureStore(Program.java:1192)
        at com.microsoft.alm.gitcredentialmanager.Program.initialize(Program.java:882)
        at com.microsoft.alm.gitcredentialmanager.Program.get(Program.java:292)
        at com.microsoft.alm.gitcredentialmanager.Program.access$200(Program.java:63)
        at com.microsoft.alm.gitcredentialmanager.Program$3.call(Program.java:284)
        at com.microsoft.alm.gitcredentialmanager.Program$3.call(Program.java:281)
        at com.microsoft.alm.gitcredentialmanager.Program.innerMain(Program.java:195)
        at com.microsoft.alm.gitcredentialmanager.Program.main(Program.java:123)
fatal: credential helper '!/home/linuxbrew/.linuxbrew/Cellar/jdk/9.0.4/bin/java -Ddebug=true -Djava.net.useSystemProxies=true -jar /home/linuxbrew/.linuxbrew/Cellar/git-credential-manager/2.0.4/libexec/git-credential-manager-2.0.4.jar' told us to quit

git config directives for user

21:35:56 user common-vm ~
 $ git config --list --show-origin
file:/home/user/.gitconfig      user.email=email@my.domain.tld
file:/home/user/.gitconfig      user.name=Martin Hartmann
file:/home/user/.gitconfig      core.commentchar=~
file:/home/user/.gitconfig      core.autocrlf=input
file:/home/user/.gitconfig      pull.rebase=true
file:/home/user/.gitconfig      push.default=simple
file:/home/user/.gitconfig      credential.helper=!/home/linuxbrew/.linuxbrew/Cellar/jdk/9.0.4/bin/java -Duser.home=$HOME -Ddebug=false -Djava.net.useSystemProxies=true -jar /home/linuxbrew/.linuxbrew/Cellar/git-credential-manager/2.0.4/libexec/git-credential-manager-2.0.4.jar
file:/home/user/.gitconfig      credential.canfallbacktoinsecurestore=true
file:/home/user/.gitconfig      alias.hist=log --graph --oneline --date-order --decorate --color --all
file:/home/user/.gitconfig      alias.histo=log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)''          %C(white)%s%C(reset) %C(dim white)- %an%C(reset) ' --all
file:/home/user/.gitconfig      alias.s=status -uno
file:/home/user/.gitconfig      alias.rc=rebase --continue
file:/home/user/.gitconfig      alias.ra=rebase --abort

git config directives for sudo

21:35:59 user common-vm ~
 $ sudo git config --list --show-origin
file:/home/user/.gitconfig      user.email=email@my.domain.tld
file:/home/user/.gitconfig      user.name=Martin Hartmann
file:/home/user/.gitconfig      core.commentchar=~
file:/home/user/.gitconfig      core.autocrlf=input
file:/home/user/.gitconfig      pull.rebase=true
file:/home/user/.gitconfig      push.default=simple
file:/home/user/.gitconfig      credential.helper=!/home/linuxbrew/.linuxbrew/Cellar/jdk/9.0.4/bin/java -Duser.home=$HOME -Ddebug=false -Djava.net.useSystemProxies=true -jar /home/linuxbrew/.linuxbrew/Cellar/git-credential-manager/2.0.4/libexec/git-credential-manager-2.0.4.jar
file:/home/user/.gitconfig      credential.canfallbacktoinsecurestore=true
file:/home/user/.gitconfig      alias.hist=log --graph --oneline --date-order --decorate --color --all
file:/home/user/.gitconfig      alias.histo=log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)''          %C(white)%s%C(reset) %C(dim white)- %an%C(reset) ' --all
file:/home/user/.gitconfig      alias.s=status -uno
file:/home/user/.gitconfig      alias.rc=rebase --continue
file:/home/user/.gitconfig      alias.ra=rebase --abort

git config directives for root

21:36:02 user common-vm ~
 $ sudo -i
root@common-vm:~# git config --list --show-origin
file:/root/.gitconfig   user.useconfigonly=from root .gitconfig

Contents of /root/.gitconfig

root@common-vm:~# cat /root/.gitconfig
[user]
        useConfigOnly = from root .gitconfig

Which is shown using git push whilst being root, but never shown using [sudo] git config --list.

ghost commented 6 years ago

Duplicate of #103 (The error is the same here; it seems like this is the same problem).