summaryrefslogtreecommitdiff
path: root/credential.c
AgeCommit message (Collapse)Author
2025-01-21Merge branch 'ps/the-repository'Junio C Hamano
More code paths have a repository passed through the callchain, instead of assuming the primary the_repository object. * ps/the-repository: match-trees: stop using `the_repository` graph: stop using `the_repository` add-interactive: stop using `the_repository` tmp-objdir: stop using `the_repository` resolve-undo: stop using `the_repository` credential: stop using `the_repository` mailinfo: stop using `the_repository` diagnose: stop using `the_repository` server-info: stop using `the_repository` send-pack: stop using `the_repository` serve: stop using `the_repository` trace: stop using `the_repository` pager: stop using `the_repository` progress: stop using `the_repository`
2025-01-13Sync with Git 2.47.2Junio C Hamano
Git 2.47.2 # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEE4fA2sf7nIh/HeOzvsLXohpav5ssFAmdkT1sACgkQsLXohpav # 5svdhRAAq0WoZIg+33vYNNVSTm3Ux9RJslmXs3lQuhuUJ61hK/28drSLU29GH7x7 # 3nmmjp1cegnXRVLBAfoYDdzPprNNrQFQEHQEzgG/GDZw0OXn+WTZuNyrrUYoa+sd # QSLlElRj2qrpHIMOsMIBKBSNB+qjJHOMGdxcBAS768TfnQpGIpc1KJa24TxsVBzC # ScP4uvrFfPyQrqFUgiUhCeqLnO/6T5i/QAn/8cS5a1+zor5ZHSlw28TZTOxN2odo # Rulp/FtehiDEzmRowgD3M4fImAPY6Ib6VORCYASqpJFFla30tu2bQqEi6raOMTec # hg5Ibkmj6fHFONaYvoTMRkYHmtUnNgIPU/CYPwswNk8w1+PPQfJ+TYjBXOQgdTLW # F0azHBHh7NRmEHVydiF9CqjgNVRzjO4IEZfGqXNFPPMvR6UUzDaIkrpYbwXBFMin # GNPV3QISeXj9ROjJoCv0nclXETwWemykjZlD6b5krXn5TaJlFb+69qJvXrCLq5WY # EoevSqKkB9HVK9si7P8Sh1cPGOr3kfiFPmMNKFVI8l0+iDFgBywOomWNS/JEzqu1 # nN142DKdL1W/rkeMUhbX2h11CZNvHKIOy3iaA4MTOing8/eMzyUUQ73Ck7odYs4f # rZ0tTXKJhxojPvBpTxYe9SxM0bDLREiOv0zX76+sIuhbAQCmk0o= # =MNNf # -----END PGP SIGNATURE----- # gpg: Signature made Thu 19 Dec 2024 08:52:43 AM PST # gpg: using RSA key E1F036B1FEE7221FC778ECEFB0B5E88696AFE6CB # gpg: Good signature from "Junio C Hamano <gitster@pobox.com>" [ultimate] # gpg: aka "Junio C Hamano <junio@pobox.com>" [ultimate] # gpg: aka "Junio C Hamano <jch@google.com>" [ultimate] * tag 'v2.47.2': Git 2.47.2 Git 2.46.3 Git 2.45.3 Git 2.44.3 Git 2.43.6 Git 2.42.4 Git 2.41.3 Git 2.40.4 credential: disallow Carriage Returns in the protocol by default credential: sanitize the user prompt credential_format(): also encode <host>[:<port>] t7300: work around platform-specific behaviour with long paths on MinGW compat/regex: fix argument order to calloc(3) mingw: drop bogus (and unneeded) declaration of `_pgmptr` ci: remove 'Upload failed tests' directories' step from linux32 jobs
2024-12-18credential: stop using `the_repository`Patrick Steinhardt
Stop using `the_repository` in the "credential" subsystem by passing in a repository when filling, approving or rejecting credentials. Adjust callers accordingly by using `the_repository`. While there may be some callers that have a repository available in their context, this trivial conversion allows for easier verification and bubbles up the use of `the_repository` by one level. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06global: mark code units that generate warnings with `-Wsign-compare`Patrick Steinhardt
Mark code units that generate warnings with `-Wsign-compare`. This allows for a structured approach to get rid of all such warnings over time in a way that can be easily measured. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-11-26Sync with 2.46.3Johannes Schindelin
* maint-2.46: Git 2.46.3 Git 2.45.3 Git 2.44.3 Git 2.43.6 Git 2.42.4 Git 2.41.3 Git 2.40.4 credential: disallow Carriage Returns in the protocol by default credential: sanitize the user prompt credential_format(): also encode <host>[:<port>] t7300: work around platform-specific behaviour with long paths on MinGW compat/regex: fix argument order to calloc(3) mingw: drop bogus (and unneeded) declaration of `_pgmptr` ci: remove 'Upload failed tests' directories' step from linux32 jobs
2024-11-26Sync with 2.45.3Johannes Schindelin
* maint-2.45: Git 2.45.3 Git 2.44.3 Git 2.43.6 Git 2.42.4 Git 2.41.3 Git 2.40.4 credential: disallow Carriage Returns in the protocol by default credential: sanitize the user prompt credential_format(): also encode <host>[:<port>] t7300: work around platform-specific behaviour with long paths on MinGW compat/regex: fix argument order to calloc(3) mingw: drop bogus (and unneeded) declaration of `_pgmptr` ci: remove 'Upload failed tests' directories' step from linux32 jobs
2024-11-26Sync with 2.42.4Johannes Schindelin
* maint-2.42: Git 2.42.4 Git 2.41.3 Git 2.40.4 credential: disallow Carriage Returns in the protocol by default credential: sanitize the user prompt credential_format(): also encode <host>[:<port>] t7300: work around platform-specific behaviour with long paths on MinGW compat/regex: fix argument order to calloc(3) mingw: drop bogus (and unneeded) declaration of `_pgmptr` ci: remove 'Upload failed tests' directories' step from linux32 jobs
2024-11-26Sync with 2.41.3Johannes Schindelin
* maint-2.41: Git 2.41.3 Git 2.40.4 credential: disallow Carriage Returns in the protocol by default credential: sanitize the user prompt credential_format(): also encode <host>[:<port>] t7300: work around platform-specific behaviour with long paths on MinGW compat/regex: fix argument order to calloc(3) mingw: drop bogus (and unneeded) declaration of `_pgmptr` ci: remove 'Upload failed tests' directories' step from linux32 jobs
2024-11-26Sync with 2.40.4Johannes Schindelin
* maint-2.40: Git 2.40.4 credential: disallow Carriage Returns in the protocol by default credential: sanitize the user prompt credential_format(): also encode <host>[:<port>] t7300: work around platform-specific behaviour with long paths on MinGW compat/regex: fix argument order to calloc(3) mingw: drop bogus (and unneeded) declaration of `_pgmptr` ci: remove 'Upload failed tests' directories' step from linux32 jobs
2024-11-26credential: disallow Carriage Returns in the protocol by defaultJohannes Schindelin
While Git has documented that the credential protocol is line-based, with newlines as terminators, the exact shape of a newline has not been documented. From Git's perspective, which is firmly rooted in the Linux ecosystem, it is clear that "a newline" means a Line Feed character. However, even Git's credential protocol respects Windows line endings (a Carriage Return character followed by a Line Feed character, "CR/LF") by virtue of using `strbuf_getline()`. There is a third category of line endings that has been used originally by MacOS, and that is respected by the default line readers of .NET and node.js: bare Carriage Returns. Git cannot handle those, and what is worse: Git's remedy against CVE-2020-5260 does not catch when credential helpers are used that interpret bare Carriage Returns as newlines. Git Credential Manager addressed this as CVE-2024-50338, but other credential helpers may still be vulnerable. So let's not only disallow Line Feed characters as part of the values in the credential protocol, but also disallow Carriage Return characters. In the unlikely event that a credential helper relies on Carriage Returns in the protocol, introduce an escape hatch via the `credential.protectProtocol` config setting. This addresses CVE-2024-52006. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2024-11-26credential: sanitize the user promptJohannes Schindelin
When asking the user interactively for credentials, we want to avoid misleading them e.g. via control sequences that pretend that the URL targets a trusted host when it does not. While Git learned, over the course of the preceding commits, to disallow URLs containing URL-encoded control characters by default, credential helpers are still allowed to specify values very freely (apart from Line Feed and NUL characters, anything is allowed), and this would allow, say, a username containing control characters to be specified that would then be displayed in the interactive terminal prompt asking the user for the password, potentially sending those control characters directly to the terminal. This is undesirable because control characters can be used to mislead users to divulge secret information to untrusted sites. To prevent such an attack vector, let's add a `git_prompt()` that forces the displayed text to be sanitized, i.e. displaying question marks instead of control characters. Note: While this commit's diff changes a lot of `user@host` strings to `user%40host`, which may look suspicious on the surface, there is a good reason for that: this string specifies a user name, not a <username>@<hostname> combination! In the context of t5541, the actual combination looks like this: `user%40@127.0.0.1:5541`. Therefore, these string replacements document a net improvement introduced by this commit, as `user@host@127.0.0.1` could have left readers wondering where the user name ends and where the host name begins. Hinted-at-by: Jeff King <peff@peff.net> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2024-11-26credential_format(): also encode <host>[:<port>]Johannes Schindelin
An upcoming change wants to sanitize the credential password prompt where a URL is displayed that may potentially come from a `.gitmodules` file. To this end, the `credential_format()` function is employed. To sanitize the host name (and optional port) part of the URL, we need a new mode of the `strbuf_add_percentencode()` function because the current mode is both too strict and too lenient: too strict because it encodes `:`, `[` and `]` (which should be left unencoded in `<host>:<port>` and in IPv6 addresses), and too lenient because it does not encode invalid host name characters `/`, `_` and `~`. So let's introduce and use a new mode specifically to encode the host name and optional port part of a URI, leaving alpha-numerical characters, periods, colons and brackets alone and encoding all others. This only leads to a change of behavior for URLs that contain invalid host names. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2024-09-30Merge branch 'ds/background-maintenance-with-credential'Junio C Hamano
Background tasks "git maintenance" runs may need to use credential information when going over the network, but a credential helper may work only in an interactive environment, and end up blocking a scheduled task waiting for UI. Credential helpers can now behave differently when they are not running interactively. * ds/background-maintenance-with-credential: scalar: configure maintenance during 'reconfigure' maintenance: add custom config to background jobs credential: add new interactive config option
2024-09-20credential: add new interactive config optionDerrick Stolee
When scripts or background maintenance wish to perform HTTP(S) requests, there is a risk that our stored credentials might be invalid. At the moment, this causes the credential helper to ping the user and block the process. Even if the credential helper does not ping the user, Git falls back to the 'askpass' method, which includes a direct ping to the user via the terminal. Even setting the 'core.askPass' config as something like 'echo' will causes Git to fallback to a terminal prompt. It uses git_terminal_prompt(), which finds the terminal from the environment and ignores whether stdin has been redirected. This can also block the process awaiting input. Create a new config option to prevent user interaction, favoring a failure to a blocked process. The chosen name, 'credential.interactive', is taken from the config option used by Git Credential Manager to already avoid user interactivity, so there is already one credential helper that integrates with this option. However, older versions of Git Credential Manager also accepted other string values, including 'auto', 'never', and 'always'. The modern use is to use a boolean value, but we should still be careful that some users could have these non-booleans. Further, we should respect 'never' the same as 'false'. This is respected by the implementation and test, but not mentioned in the documentation. The implementation for the Git interactions takes place within credential_getpass(). The method prototype is modified to return an 'int' instead of 'void'. This allows us to detect that no attempt was made to fill the given credential, changing the single caller slightly. Also, a new trace2 region is added around the interactive portion of the credential request. This provides a way to measure the amount of time spent in that region for commands that _are_ interactive. It also makes a conventient way to test that the config option works with 'test_region'. Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-08-13global: prepare for hiding away repo-less config functionsPatrick Steinhardt
We're about to hide config functions that implicitly depend on `the_repository` behind the `USE_THE_REPOSITORY_VARIABLE` macro. This will uncover a bunch of dependents that transitively relied on the global variable, but didn't define the macro yet. Adapt them such that we define the macro to prepare for this change. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-06-06credential: clear expired c->credential, unify secret clearingAaron Plattner
When a struct credential expires, credential_fill() clears c->password so that clients don't try to use it later. However, a struct cred that uses an alternate authtype won't have a password, but might have a credential stored in c->credential. This is a problem, for example, when an OAuth2 bearer token is used. In the system I'm using, the OAuth2 configuration generates and caches a bearer token that is valid for an hour. After the token expires, git needs to call back into the credential helper to use a stored refresh token to get a new bearer token. But if c->credential is still non-NULL, git will instead try to use the expired token and fail with an error: fatal: Authentication failed for 'https://<oauth2-enabled-server>/repository' And on the server: [auth_openidc:error] [client <ip>:34012] oidc_proto_validate_exp: "exp" validation failure (1717522989): JWT expired 224 seconds ago Fix this by clearing both c->password and c->credential for an expired struct credential. While we're at it, use credential_clear_secrets() wherever both c->password and c->credential are being cleared. Update comments in credential.h to mention the new struct fields. Signed-off-by: Aaron Plattner <aplattner@nvidia.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-04-16credential: add method for querying capabilitiesbrian m. carlson
Right now, there's no specific way to determine whether a credential helper or git credential itself supports a given set of capabilities. It would be helpful to have such a way, so let's let credential helpers and git 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. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-04-16credential-cache: implement authtype capabilitybrian m. carlson
Now that we have full support in Git for the authtype capability, let's add support to the cache credential helper. When parsing data, we always set the initial capabilities because we're the helper, and we need both the initial and helper capabilities to be set in order to have the helper capabilities take effect. When emitting data, always emit the supported capability and make sure we emit items only if we have them and they're supported by the caller. Since we may no longer have a username or password, be sure to emit those conditionally as well so we don't segfault on a NULL pointer. Similarly, when comparing credentials, consider both the password and credential fields when we're matching passwords. Adjust the partial credential detection code so that we can store credentials missing a username or password as long as they have an authtype and credential. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-04-16credential: add support for multistage credential roundsbrian 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. Keep the state[] headers between iterations, but only use them to send to the helper and only consider the new ones we read from the credential helper to be valid on subsequent iterations. That avoids us passing stale data when we finally approve or reject the credential. Similarly, clear the multistage and wwwauth[] values appropriately so that we don't pass stale data or think we're trying a multiround response when we're not. Remove the credential values so that we can actually fill a second time with new responses. 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). In our tests, handle creating multiple response output files from our helper so we can verify that each of the messages sent is correct. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-04-16credential: enable state capabilitybrian m. carlson
Now that we've implemented the state capability, let's send it along by default when filling credentials so we can make use of it. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-04-16credential: add an argument to keep statebrian m. carlson
Until now, our credential code has mostly deal with usernames and passwords and we've let libcurl deal with the variant of authentication to be used. However, now that we have the credential value, the credential helper can take control of the authentication, so the value provided might be something that's generated, such as a Digest hash value. In such a case, it would be helpful for a credential helper that gets an erase or store command to be able to keep track of an identifier for the original secret that went into the computation. Furthermore, some types of authentication, such as NTLM and Kerberos, actually need two round trips to authenticate, which will require that the credential helper keep some state. In order to allow for these use cases and others, allow storing state in a field called "state[]". This value is passed back to the credential helper that created it, which avoids confusion caused by parsing values from different helpers. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-04-16credential: add a field called "ephemeral"brian m. carlson
Now that we have support for a wide variety of types of authentication, it's important to indicate to other credential helpers whether they should store credentials, since not every credential helper may intuitively understand all possible values of the authtype field. Do so with a boolean field called "ephemeral", to indicate whether the credential is expected to be temporary. For example, in HTTP Digest authentication, the Authorization header value is based off a nonce. It isn't useful to store this value for later use because reusing the credential long term will not result in successful authentication due to the nonce necessarily differing. An additional case is potentially short-lived credentials, which may last only a few hours. It similarly wouldn't be helper for other credential helpers to attempt to provide these much later. We do still pass the value to "git credential store" or "git credential erase", since it may be helpful to the original helper to know whether the operation was successful. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-04-16credential: gate new fields on capabilitybrian m. carlson
We support the new credential and authtype fields, but we lack a way to indicate to a credential helper that we'd like them to be used. Without some sort of indication, the credential helper doesn't know if it should try to provide us a username and password, or a pre-encoded credential. For example, the helper might prefer a more restricted Bearer token if pre-encoded credentials are possible, but might have to fall back to more general username and password if not. Let's provide a simple way to indicate whether Git (or, for that matter, the helper) is capable of understanding the authtype and credential fields. We send this capability when we generate a request, and the other side may reply to indicate to us that it does, too. For now, don't enable sending capabilities for the HTTP code. In a future commit, we'll introduce appropriate handling for that code, which requires more in-depth work. The logic for determining whether a capability is supported may seem complex, but it is not. At each stage, we emit the capability to the following stage if all preceding stages have declared it. Thus, if the caller to git credential fill didn't declare it, then we won't send it to the helper, and if fill's caller did send but the helper doesn't understand it, then we won't send it on in the response. If we're an internal user, then we know about all capabilities and will request them. For "git credential approve" and "git credential reject", we set the helper capability before calling the helper, since we assume that the input we're getting from the external program comes from a previous call to "git credential fill", and thus we'll invoke send a capability to the helper if and only if we got one from the standard input, which is the correct behavior. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-04-16credential: add a field for pre-encoded credentialsbrian m. carlson
At the moment, our credential code wants to find a username and password for access, which, for HTTP, it will pass to libcurl to encode and process. However, many users want to use authentication schemes that libcurl doesn't support, such as Bearer authentication. In these schemes, the secret is not a username and password pair, but some sort of token that meets the production for authentication data in the RFC. In fact, in general, it's useful to allow our credential helper to have knowledge about what specifically to put in the protocol header. Thus, add a field, credential, which contains data that's preencoded to be suitable for the protocol in question. If we have such data, we need neither a username nor a password, so make that adjustment as well. It is in theory possible to reuse the password field for this. However, if we do so, we must know whether the credential helper supports our new scheme before sending it data, which necessitates some sort of capability inquiry, because otherwise an uninformed credential helper would store our preencoded data as a password, which would fail the next time we attempted to connect to the remote server. This design is substantially simpler, and we can hint to the credential helper that we support this approach with a simple new field instead of needing to query it first. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-04-16credential: add an authtype fieldbrian 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. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-08-29credential: mark unused parameter in urlmatch callbackJeff King
Our select_all() callback does not need to actually look at its parameters, since the point is to match everything. But we need to mark its parameters to satisfy -Wunused-parameter. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-06-28config: add ctx arg to config_fn_tGlen Choo
Add a new "const struct config_context *ctx" arg to config_fn_t to hold additional information about the config iteration operation. config_context has a "struct key_value_info kvi" member that holds metadata about the config source being read (e.g. what kind of config source it is, the filename, etc). In this series, we're only interested in .kvi, so we could have just used "struct key_value_info" as an arg, but config_context makes it possible to add/adjust members in the future without changing the config_fn_t signature. We could also consider other ways of organizing the args (e.g. moving the config name and value into config_context or key_value_info), but in my experiments, the incremental benefit doesn't justify the added complexity (e.g. a config_fn_t will sometimes invoke another config_fn_t but with a different config value). In subsequent commits, the .kvi member will replace the global "struct config_reader" in config.c, making config iteration a global-free operation. It requires much more work for the machinery to provide meaningful values of .kvi, so for now, merely change the signature and call sites, pass NULL as a placeholder value, and don't rely on the arg in any meaningful way. Most of the changes are performed by contrib/coccinelle/config_fn_ctx.pending.cocci, which, for every config_fn_t: - Modifies the signature to accept "const struct config_context *ctx" - Passes "ctx" to any inner config_fn_t, if needed - Adds UNUSED attributes to "ctx", if needed Most config_fn_t instances are easily identified by seeing if they are called by the various config functions. Most of the remaining ones are manually named in the .cocci patch. Manual cleanups are still needed, but the majority of it is trivial; it's either adjusting config_fn_t that the .cocci patch didn't catch, or adding forward declarations of "struct config_context ctx" to make the signatures make sense. The non-trivial changes are in cases where we are invoking a config_fn_t outside of config machinery, and we now need to decide what value of "ctx" to pass. These cases are: - trace2/tr2_cfg.c:tr2_cfg_set_fl() This is indirectly called by git_config_set() so that the trace2 machinery can notice the new config values and update its settings using the tr2 config parsing function, i.e. tr2_cfg_cb(). - builtin/checkout.c:checkout_main() This calls git_xmerge_config() as a shorthand for parsing a CLI arg. This might be worth refactoring away in the future, since git_xmerge_config() can call git_default_config(), which can do much more than just parsing. Handle them by creating a KVI_INIT macro that initializes "struct key_value_info" to a reasonable default, and use that to construct the "ctx" arg. Signed-off-by: Glen Choo <chooglen@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-06-15credential: avoid erasing distinct passwordM Hickford
Test that credential helpers do not erase a password distinct from the input. Such calls can happen when multiple credential helpers are configured. Fixes for credential-cache and credential-store. Signed-off-by: M Hickford <mirth.hickford@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-05-10Merge branch 'mh/credential-oauth-refresh-token'Junio C Hamano
The credential subsystem learns to help OAuth framework. * mh/credential-oauth-refresh-token: credential: new attribute oauth_refresh_token
2023-05-10Merge branch 'tb/credential-long-lines'Junio C Hamano
The implementation of credential helpers used fgets() over fixed size buffers to read protocol messages, causing the remainder of the folded long line to trigger unexpected behaviour, which has been corrected. * tb/credential-long-lines: contrib/credential: embiggen fixed-size buffer in wincred contrib/credential: avoid fixed-size buffer in libsecret contrib/credential: .gitignore libsecret build artifacts contrib/credential: remove 'gnome-keyring' credential helper contrib/credential: avoid fixed-size buffer in osxkeychain t/lib-credential.sh: ensure credential helpers handle long headers credential.c: store "wwwauth[]" values in `credential_read()`
2023-05-01credential.c: store "wwwauth[]" values in `credential_read()`Taylor Blau
Teach git-credential to read "wwwauth[]" value(s) when parsing the output of a credential helper. These extra headers are not needed for Git's own HTTP support to use the feature internally, but the feature would not be available for a scripted caller (say, git-remote-mediawiki providing the header in the same way). As a bonus, this also makes it easier to use wwwauth[] in synthetic credential inputs in our test suite. Co-authored-by: Jeff King <peff@peff.net> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-04-24treewide: remove cache.h inclusion due to previous changesElijah Newren
Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-04-24treewide: be explicit about dependence on strbuf.hElijah Newren
Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-04-21credential: new attribute oauth_refresh_tokenM Hickford
Git authentication with OAuth access token is supported by every popular Git host including GitHub, GitLab and BitBucket [1][2][3]. Credential helpers Git Credential Manager (GCM) and git-credential-oauth generate OAuth credentials [4][5]. Following RFC 6749, the application prints a link for the user to authorize access in browser. A loopback redirect communicates the response including access token to the application. For security, RFC 6749 recommends that OAuth response also includes expiry date and refresh token [6]. After expiry, applications can use the refresh token to generate a new access token without user reauthorization in browser. GitLab and BitBucket set the expiry at two hours [2][3]. (GitHub doesn't populate expiry or refresh token.) However the Git credential protocol has no attribute to store the OAuth refresh token (unrecognised attributes are silently discarded). This means that the user has to regularly reauthorize the helper in browser. On a browserless system, this is particularly intrusive, requiring a second device. Introduce a new attribute oauth_refresh_token. This is especially useful when a storage helper and a read-only OAuth helper are configured together. Recall that `credential fill` calls each helper until it has a non-expired password. ``` [credential] helper = storage # eg. cache or osxkeychain helper = oauth ``` The OAuth helper can use the stored refresh token forwarded by `credential fill` to generate a fresh access token without opening the browser. See https://github.com/hickford/git-credential-oauth/pull/3/files for an implementation tested with this patch. Add support for the new attribute to credential-cache. Eventually, I hope to see support in other popular storage helpers. Alternatives considered: ask helpers to store all unrecognised attributes. This seems excessively complex for no obvious gain. Helpers would also need extra information to distinguish between confidential and non-confidential attributes. Workarounds: GCM abuses the helper get/store/erase contract to store the refresh token during credential *get* as the password for a fictitious host [7] (I wrote this hack). This workaround is only feasible for a monolithic helper with its own storage. [1] https://github.blog/2012-09-21-easier-builds-and-deployments-using-git-over-https-and-oauth/ [2] https://docs.gitlab.com/ee/api/oauth2.html#access-git-over-https-with-access-token [3] https://support.atlassian.com/bitbucket-cloud/docs/use-oauth-on-bitbucket-cloud/#Cloning-a-repository-with-an-access-token [4] https://github.com/GitCredentialManager/git-credential-manager [5] https://github.com/hickford/git-credential-oauth [6] https://datatracker.ietf.org/doc/html/rfc6749#section-5.1 [7] https://github.com/GitCredentialManager/git-credential-manager/blob/66b94e489ad8cc1982836355493e369770b30211/src/shared/GitLab/GitLabHostProvider.cs#L207 Signed-off-by: M Hickford <mirth.hickford@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-03-21abspath.h: move absolute path functions from cache.hElijah Newren
This is another step towards letting us remove the include of cache.h in strbuf.c. It does mean that we also need to add includes of abspath.h in a number of C files. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-03-21treewide: be explicit about dependence on gettext.hElijah Newren
Dozens of files made use of gettext functions, without explicitly including gettext.h. This made it more difficult to find which files could remove a dependence on cache.h. Make C files explicitly include gettext.h if they are using it. However, while compat/fsmonitor/fsm-ipc-darwin.c should also gain an include of gettext.h, it was left out to avoid conflicting with an in-flight topic. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-03-17Merge branch 'mc/credential-helper-www-authenticate'Junio C Hamano
Allow information carried on the WWW-AUthenticate header to be passed to the credential helpers. * mc/credential-helper-www-authenticate: credential: add WWW-Authenticate header to cred requests http: read HTTP WWW-Authenticate response headers t5563: add tests for basic and anoymous HTTP access
2023-02-27credential: add WWW-Authenticate header to cred requestsMatthew John Cheetham
Add the value of the WWW-Authenticate response header to credential requests. Credential helpers that understand and support HTTP authentication and authorization can use this standard header (RFC 2616 Section 14.47 [1]) to generate valid credentials. WWW-Authenticate headers can contain information pertaining to the authority, authentication mechanism, or extra parameters/scopes that are required. The current I/O format for credential helpers only allows for unique names for properties/attributes, so in order to transmit multiple header values (with a specific order) we introduce a new convention whereby a C-style array syntax is used in the property name to denote multiple ordered values for the same property. In this case we send multiple `wwwauth[]` properties where the order that the repeated attributes appear in the conversation reflects the order that the WWW-Authenticate headers appeared in the HTTP response. Add a set of tests to exercise the HTTP authentication header parsing and the interop with credential helpers. Credential helpers will receive WWW-Authenticate information in credential requests. [1] https://datatracker.ietf.org/doc/html/rfc2616#section-14.47 Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-27http: read HTTP WWW-Authenticate response headersMatthew John Cheetham
Read and store the HTTP WWW-Authenticate response headers made for a particular request. This will allow us to pass important authentication challenge information to credential helpers or others that would otherwise have been lost. libcurl only provides us with the ability to read all headers recieved for a particular request, including any intermediate redirect requests or proxies. The lines returned by libcurl include HTTP status lines delinating any intermediate requests such as "HTTP/1.1 200". We use these lines to reset the strvec of WWW-Authenticate header values as we encounter them in order to only capture the final response headers. The collection of all header values matching the WWW-Authenticate header is complicated by the fact that it is legal for header fields to be continued over multiple lines, but libcurl only gives us each physical line a time, not each logical header. This line folding feature is deprecated in RFC 7230 [1] but older servers may still emit them, so we need to handle them. In the future [2] we may be able to leverage functions to read headers from libcurl itself, but as of today we must do this ourselves. [1] https://www.rfc-editor.org/rfc/rfc7230#section-3.2 [2] https://daniel.haxx.se/blog/2022/03/22/a-headers-api-for-libcurl/ Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-22credential: new attribute password_expiry_utcM Hickford
Some passwords have an expiry date known at generation. This may be years away for a personal access token or hours for an OAuth access token. When multiple credential helpers are configured, `credential fill` tries each helper in turn until it has a username and password, returning early. If Git authentication succeeds, `credential approve` stores the successful credential in all helpers. If authentication fails, `credential reject` erases matching credentials in all helpers. Helpers implement corresponding operations: get, store, erase. The credential protocol has no expiry attribute, so helpers cannot store expiry information. Even if a helper returned an improvised expiry attribute, git credential discards unrecognised attributes between operations and between helpers. This is a particular issue when a storage helper and a credential-generating helper are configured together: [credential] helper = storage # eg. cache or osxkeychain helper = generate # eg. oauth `credential approve` stores the generated credential in both helpers without expiry information. Later `credential fill` may return an expired credential from storage. There is no workaround, no matter how clever the second helper. The user sees authentication fail (a retry will succeed). Introduce a password expiry attribute. In `credential fill`, ignore expired passwords and continue to query subsequent helpers. In the example above, `credential fill` ignores the expired password and a fresh credential is generated. If authentication succeeds, `credential approve` replaces the expired password in storage. If authentication fails, the expired credential is erased by `credential reject`. It is unnecessary but harmless for storage helpers to self prune expired credentials. Add support for the new attribute to credential-cache. Eventually, I hope to see support in other popular storage helpers. Example usage in a credential-generating helper https://github.com/hickford/git-credential-oauth/pull/16 Signed-off-by: M Hickford <mirth.hickford@gmail.com> Reviewed-by: Calvin Wan <calvinwan@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-03-04urlmatch.c: add and use a *_release() functionÆvar Arnfjörð Bjarmason
Plug a memory leak in credential_apply_config() by adding and using a new urlmatch_config_release() function. This just does a string_list_clear() on the "vars" member. This finished up work on normalizing the init/free pattern in this API, started in 73ee449bbf2 (urlmatch.[ch]: add and use URLMATCH_CONFIG_INIT, 2021-10-01). Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-10-01urlmatch.[ch]: add and use URLMATCH_CONFIG_INITÆvar Arnfjörð Bjarmason
Change the initialization pattern of "struct urlmatch_config" to use an *_INIT macro and designated initializers. Right now there's no other "struct" member of "struct urlmatch_config" which would require its own *_INIT, but it's good practice not to assume that. Let's also change this to a designated initializer while we're at it. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-25credential: fix leak in credential_apply_config()Mike Hommey
Signed-off-by: Mike Hommey <mh@glandium.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-07-01*.c *_init(): define in terms of corresponding *_INIT macroÆvar Arnfjörð Bjarmason
Change the common patter in the codebase of duplicating the initialization logic between an *_INIT macro and a corresponding *_init() function to use the macro as the canonical source of truth. Now we no longer need to keep the function up-to-date with the macro version. This implements a suggestion by Jeff King who found that under -O2 [1] modern compilers will init new version in place without the extra copy[1]. The performance of a single *_init() won't matter in most cases, but even if it does we're going to be producing efficient machine code to perform these operations. 1. https://lore.kernel.org/git/YNyrDxUO1PlGJvCn@coredump.intra.peff.net/ Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-10-03credential: treat CR/LF as line endings in the credential protocolNikita Leonov
This fix makes using Git credentials more friendly to Windows users: it allows a credential helper to communicate using CR/LF line endings ("DOS line endings" commonly found on Windows) instead of LF-only line endings ("Unix line endings"). Note that this changes the behavior a bit: if a credential helper produces, say, a password with a trailing Carriage Return character, that will now be culled even when the rest of the lines end only in Line Feed characters, indicating that the Carriage Return was not meant to be part of the line ending. In practice, it seems _very_ unlikely that something like this happens. Passwords usually need to consist of non-control characters, URLs need to have special characters URL-encoded, and user names, well, are names. However, it _does_ help on Windows, where CR/LF line endings are common: as unrecognized commands are simply ignored by the credential machinery, even a command like `quit\r` (which is clearly intended to abort) would simply be ignored (silently) by Git. So let's change the credential machinery to accept both CR/LF and LF line endings. While we do this for the credential helper protocol, we do _not_ adjust `git credential-cache--daemon` (which won't work on Windows, anyway, because it requires Unix sockets) nor `git credential-store` (which writes the file `~/.git-credentials` which we consider an implementation detail that should be opaque to the user, read: we do expect users _not_ to edit this file manually). Signed-off-by: Nikita Leonov <nykyta.leonov@gmail.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-08-26run_command: teach API users to use embedded 'args' moreJunio C Hamano
The child_process structure has an embedded strvec for formulating the command line argument list these days, but code that predates the wide use of it prepared a separate char *argv[] array and manually set the child_process.argv pointer point at it. Teach these old-style code to lose the separate argv[] array. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-05-05Merge branch 'js/partial-urlmatch'Junio C Hamano
The same as js/partial-urlmatch-2.17, built on more recent codebase to avoid unnecessary merge conflicts. * js/partial-urlmatch: credential: handle `credential.<partial-URL>.<key>` again credential: optionally allow partial URLs in credential_from_url_gently()
2020-05-05Merge branch 'js/partial-urlmatch-2.17'Junio C Hamano
Recent updates broke parsing of "credential.<url>.<key>" where <url> is not a full URL (e.g. [credential "https://"] helper = ...) stopped working, which has been corrected. * js/partial-urlmatch-2.17: credential: handle `credential.<partial-URL>.<key>` again credential: optionally allow partial URLs in credential_from_url_gently() credential: fix grammar
2020-05-05Merge branch 'bc/wildcard-credential'Junio C Hamano
Update the parser used for credential.<URL>.<variable> configuration, to handle <URL>s with '/' in them correctly. * bc/wildcard-credential: credential: fix matching URLs with multiple levels in path
2020-04-29credential: handle `credential.<partial-URL>.<key>` againJohannes Schindelin
In the patches for CVE-2020-11008, the ability to specify credential settings in the config for partial URLs got lost. For example, it used to be possible to specify a credential helper for a specific protocol: [credential "https://"] helper = my-https-helper Likewise, it used to be possible to configure settings for a specific host, e.g.: [credential "dev.azure.com"] useHTTPPath = true Let's reinstate this behavior. While at it, increase the test coverage to document and verify the behavior with a couple other categories of partial URLs. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Reviewed-by: Carlo Marcelo Arenas Belón <carenas@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>