Reputation: 1022
I'm using Git on Windows, on a corporate network where I'm behind an HTTP proxy with Basic authentication. Outbound SSH doesn't work, so I have to use HTTPS through the proxy.
I'm aware of how to use git config http.proxy
to configure the settings as http://[username]:[password]@[proxy]:[port]
.
However, particularly as this is a shared machine, I'd rather not store my password in my .gitconfig
. Additionally, changing my .gitconfig
using the git config
command leaves my password in my bash history, so even if I remember to clear my .gitconfig
at the end of the session, I'll almost certainly forget to clear my history as well.
I've tried setting http.proxy
without a password, in the vain hope that I'd get a prompt asking me for my password when I try to push/pull, but I only get a 407 Proxy Authentication Required. All the information I've found online seems to either ignore the issues with having the password saved in plaintext in .gitconfig
, or deals with NTLM proxies.
I'm quite happy to type my proxy details every time I need to connect - the best solution I can see at the moment is writing a wrapper script that will prompt for my password and set that as an environment variable when calling git
proper. Is this a decent solution, and are there any security implications to setting an environment variable for a single call in a script? Preferably, are there any built-in settings or existing tools that I can use for this?
Upvotes: 56
Views: 109209
Reputation: 1324337
Git 2.46 should offer an alternative to the HTTP proxy server I mentioned in my 2014-2020 answer:
With Git 2.46 (Q3 2024), batch 2, the credential helper protocol, together with the HTTP layer, have been enhanced to support authentication schemes different from username & password pair, like Bearer and NTLM.
See commit ffff4ac, commit 40220f4, commit 30c0a30, commit ac4c7cb, commit 37417b7, commit bd590bd, commit 36f7d86, commit 8470c94, commit ad9bb6d, commit 5af5cc6, commit 2ae6dc6, commit ca9ccbf, commit 6a6d6fb, commit d01c76f, commit 90765ea, commit 7046f1d (17 Apr 2024) by brian m. carlson (bk2204
).
(Merged by Junio C Hamano -- gitster
-- in commit c5c9acf, 08 May 2024)
credential
: add an authtype fieldSigned-off-by: brian m. carlson
When Git makes an HTTP request, it can negotiate the type of authentication to use with the server provided the authentication scheme is one of a few well-known types (Basic, Digest, NTLM, or Negotiate).
However, some servers wish to use other types of authentication, such as the Bearer type from OAuth2.
Since libcurl doesn't natively support this type, it isn't possible to use it, and the user is forced to specify the Authorization header using the http.extraheader setting.However, storing a plaintext token in the repository configuration is not very secure, especially if a repository can be shared by multiple parties.
We already have support for many types of secure credential storage by using credential helpers, so let's teach credential helpers how to produce credentials for an arbitrary scheme.If the credential helper specifies an authtype field, then it specifies an authentication scheme (e.g., Bearer) and the password field specifies the raw authentication token, with any encoding already specified.
We reuse the password field for this because some credential helpers store the metadata without encryption even though the password is encrypted, and we'd like to avoid insecure storage if an older version of the credential helper gets ahold of the data.The username is not used in this case, but it is still preserved for the purpose of finding the right credential if the user has multiple accounts.
If the authtype field is not specified, then the password behaves as normal and it is passed along with the username to libcurl.
Documentation:
docs
: indicate new credential protocol fieldsSigned-off-by: brian m. carlson
Now that we have new fields (authtype and credential), let's document them for users and credential helper implementers.
Indicate specifically what common values of authtype are and what values are allowed.
Note that, while common, digest and NTLM authentication are insecure because they require unsalted, uniterated password hashes to be stored.Tell users that they can continue to use a username and password even if the new capability is supported.
git credential
now includes in its man page:
authtype
This indicates that the authentication scheme in question should be used. Common values for HTTP and HTTPS include
basic
,bearer
, anddigest
, although the latter is insecure and should not be used. Ifcredential
is used, this may be set to an arbitrary string suitable for the protocol in question (usually HTTP).This value should not be sent unless the appropriate capability (see below) is provided on input.
credential
The pre-encoded credential, suitable for the protocol in question (usually HTTP). If this key is sent,
authtype
is mandatory, andusername
andpassword
are not used. For HTTP, Git concatenates theauthtype
value and this value with a single space to determine theAuthorization
header.This value should not be sent unless the appropriate capability (see below) is provided on input.
ephemeral
This boolean value indicates, if true, that the value in the
credential
field should not be saved by the credential helper because its usefulness is limited in time. For example, an HTTP Digestcredential
value is computed using a nonce and reusing it will not result in successful authentication. This may also be used for situations with short duration (e.g., 24-hour) credentials. The default value is false.The credential helper will still be invoked with
store
orerase
so that it can determine whether the operation was successful.This value should not be sent unless the appropriate capability (see below) is provided on input.
git credential
now includes in its man page:
capability[]
This signals that the caller supports the capability in question. This can be used to provide better, more specific data as part of the protocol.
The only capability currently supported is
authtype
, which indicates that theauthtype
,credential
, andephemeral
values are understood. It is not obligatory to use these values in such a case, but they should not be provided without this capability.Callers of
git credential
and credential helpers should emit the capabilities they support unconditionally, and Git will gracefully handle passing them on.Unrecognised attributes and capabilities are silently discarded.
With:
credential
: add support for multistage credential roundsSigned-off-by: brian m. carlson
Over HTTP, NTLM and Kerberos require two rounds of authentication on the client side.
It's possible that there are custom authentication schemes that also implement this same approach.
Since these are tricky schemes to implement and the HTTP library in use may not always handle them gracefully on all systems, it would be helpful to allow the credential helper to implement them instead for increased portability and robustness.To allow this to happen, add a boolean flag, continue, that indicates that instead of failing when we get a 401, we should retry another round of authentication.
However, this necessitates some changes in our current credential code so that we can make this work.Limit the number of iterations of reauthentication we do to 3. This means that if there's a problem, we'll terminate with an error message instead of retrying indefinitely and not informing the user (and possibly conducting a DoS on the server).
git credential
now includes in its man page:
continue
This is a boolean value, which, if enabled, indicates that this authentication is a non-final part of a multistage authentication step. This is common in protocols such as NTLM and Kerberos, where two rounds of client authentication are required, and setting this flag allows the credential helper to implement the multistage authentication step. This flag should only be sent if a further stage is required; that is, if another round of authentication is expected.
This value should not be sent unless the appropriate capability (see below) is provided on input. This attribute is 'one-way' from a credential helper to pass information to Git (or other programs invoking
git credential
).
You can check with:
credential
: add method for querying capabilitiesSigned-off-by: brian m. carlson
Right now, there's no specific way to determine whether a credential helper or
git credential
(man) itself supports a given set of capabilities.
It would be helpful to have such a way, so let's let credential helpers andgit credential
take an argument, "capability", which has it list the capabilities and a version number on standard output.Specifically choose a format that is slightly different from regular credential output and assume that no capabilities are supported if a non-zero exit status occurs or the data deviates from the format.
It is common for users to write small shell scripts as the argument to credential.helper, which will almost never be designed to emit capabilities.
We want callers to gracefully handle this case by assuming that they are not capable of extended support because that is almost certainly the case, and specifying the error behavior up front does this and preserves backwards compatibility in a graceful way.
git credential
now includes in its man page:
git credential' (fill|approve|reject|capability)
If the action is
capability
, git-credential will announce any capabilities it supports to standard output.
git credential
now includes in its man page:
CAPABILITY INPUT/OUTPUT FORMAT
For
git credential capability
, the format is slightly different. First, aversion 0
announcement is made to indicate the current version of the protocol, and then each capability is announced with a line likecapability authtype
. Credential helpers may also implement this format, again with thecapability
argument. Additional lines may be added in the future; callers should ignore lines which they don't understand.Because this is a new part of the credential helper protocol, older versions of Git, as well as some credential helpers, may not support it. If a non-zero exit status is received, or if the first line doesn't start with the word
version
and a space, callers should assume that no capabilities are supported.The intention of this format is to differentiate it from the credential output in an unambiguous way. It is possible to use very simple credential helpers (e.g., inline shell scripts) which always produce identical output. Using a distinct format allows users to continue to use this syntax without having to worry about correctly implementing capability advertisements or accidentally confusing callers querying for capabilities.
Upvotes: 0
Reputation: 1962
I know this is an old post but thought I should add a note. In Windows 10, I did the above command in git bash as "git config --global https.proxy http://[userid]:[passwordWithSpclChars]@url:port" ... but since my credential has special characters, I had to then edit the config file C:\USERS<userid>.gitconfig to URL encode the special characters in my credential. Then I was able to proceed with git fetch from origin.
Upvotes: 0
Reputation: 1324337
Instead of using git setting, you can also use environment variable (that you can set just for your session), as described in this answer:
set http_proxy=http://username:password@proxydomain:port
set https_proxy=http://username:password@proxydomain:port
set no_proxy=localhost,.my.company
So your wrapper script could, instead of modifying the .gitconfig
(and leaving your password in plain text) set environment variables on demand, just for your current session.
As noted by Welgriv, this is unsafe since environmental variables can be accessed by any program in user mode.
These days (2020, 5+ years later), I prefer:
set http_proxy=http://127.0.0.1:3128
set https_proxy=http://127.0.0.1:3128
With 127.0.0.1:3128 being the default URL for a genotrance/px
, a small HTTP proxy server, which will automatically authenticate through an NTLM proxy.
No password or even user to set.
Upvotes: 44
Reputation: 739
since git 2.8.0
git config --global http.proxy http://[user]@proxyhost:port
git config --global credential.helper wincred
Upvotes: 71
Reputation: 21
If you are behind Proxy server, follow this.
Make sure port 9418 is excluded from your firewall rules.Ask network administrator
Unset Proxy if it is already set:
Set the proper Proxy:
Common Errors:
Upvotes: -3
Reputation: 8569
VonC's answer doesn't always solve the problem. I don't know why, but it may depend on the proxy server - or maybe it's some other issue alltogether?
It may help to replace the git://
protocol of the repository with http://
.
Note: As in VonC's answer, you'll have to setup the http(s)_proxy
environment variables first:
set http_proxy=http://username:password@proxydomain:port
set https_proxy=http://username:password@proxydomain:port
For example, clone marble's stable git would usually be cloned like this (from the marble documentation):
git clone -b Applications/15.12 git://anongit.kde.org/marble ~/marble/sources
In windows' cmd
(assuming http_proxy
has been set), you may then have to use http[s]://
instead:
git clone -b Applications/15.12 http://anongit.kde.org/marble ~/marble/sources
Upvotes: 3