git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v2] credential: clear expired c->credential, unify secret clearing

From
Jeff King <peff@peff.net>
Date
Jun 5, 2024, 08:57 UTC
Message-ID
<20240605085733.GE2345232@coredump.intra.peff.net>
In-Reply-To
<20240604192929.3252626-1-aplattner@nvidia.com>
On Tue, Jun 04, 2024 at 12:29:28PM -0700, Aaron Plattner wrote:
Show 12 quoted lines
> @@ -528,12 +532,7 @@ void credential_reject(struct credential *c)
>  	for (i = 0; i < c->helpers.nr; i++)
>  		credential_do(c, c->helpers.items[i].string, "erase");
>  
> -	FREE_AND_NULL(c->username);
> -	FREE_AND_NULL(c->password);
> -	FREE_AND_NULL(c->credential);
> -	FREE_AND_NULL(c->oauth_refresh_token);
> -	c->password_expiry_utc = TIME_MAX;
> -	c->approved = 0;
> +	credential_clear(c);
>  }

I'm skeptical of this hunk. The caller will usually have filled in parts of a credential struct like scheme and host, and then we picked up the rest from helpers or by prompting the user. Rejecting the credential should certainly clear the bogus password field and other secrets. But should it clear the host field?

I think it may be somewhat academic for now because we'll generally exit the program immediately after rejecting the credential. But occasionally the topic comes up of retrying auth within a command. So you might have a loop like this (or knowing our http code, probably some more baroque equivalent spread across multiple functions):

  credential_from_url(&cred, url);
  for (int attempt = 0; attempt < 5; attempt++) {
	credential_fill(&cred);
	switch (do_something(url, &cred)) {
	case OK: /* it worked */
		return 0;
	case AUTH_ERROR:
		/* try again */
		credential_reject(&cred);
	}
  }
  return -1; /* too many failures */

And in that case you really want to retain the "query" parts of the credential after the reject. In this toy example you could just move the url-to-cred parsing into the loop, but in the real world it's often more complicated.

Arguably even the original code is a bit questionable for this, because we don't know if the username came from a helper or from the user, or if it was part of the original URL (e.g., "https://user@example.com/" should prompt only for the password). But it feels like this hunk is making it worse.

The rest of the patch made sense to me, though. As would using credential_clear_secrets() here to replace the equivalent lines.

-Peff
Previous: Junio C HamanoNext: Aaron Plattner
Message 8 of 13 in “credential: clear expired c->credential, unify secret clearing”
  1. credential: clear expired c->credential, unify secret clearingAaron Plattner, Jun 4, 2024
  2. Junio C HamanoJun 4, 2024
  3. brian m. carlsonJun 4, 2024
  4. Junio C HamanoJun 4, 2024
  5. Aaron PlattnerJun 4, 2024
  6. Rahul RameshbabuJun 4, 2024
  7. Junio C HamanoJun 5, 2024
  8. Jeff KingJun 5, 2024
  9. Aaron PlattnerJun 5, 2024
  10. Jeff KingJun 6, 2024
  11. Junio C HamanoJun 5, 2024
  12. Jeff KingJun 6, 2024
  13. Junio C HamanoJun 6, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.