threads / discuss / 41683

[GSOC] Microproject "Move ~/.git-credential-cache to ~/.config/git"

Subject: [GSOC] Microproject "Move ~/.git-credential-cache to ~/.config/git"

## tl;dr

30 messages between Mar 14, 2016 and Mar 18, 2016.

replies: 29people: 4as markdown or json

惠轶群· Mar 14, 2016, 14:47 UTC · lore

I'm Hui Yiqun, a master degress candidate of Tsinghua University. I'd like to participate GSOC 2016 as an developer of git.

I have basic knowledge about several programming languages (namely C, python, go and etc.), compilers and cmake which may help my development.

My github page is at [here](https://github.com/huiyiqun/). There are some tiny programs.

I took part in a CDN project last year and learnt much about TCP/IP, web service and, most importantly, cooperation. However, I really want to learn how members of an opensource project work together.

I have covered most of the available materials, such as list of ideas and micro-projects, `README.md`, `INSTALL` and `Documentation/CodingGuidelines`. So I decide to start my contribution with the microproject "Move ~/.git-credential-cache to ~/.config/git" found [here](http://git.github.io/SoC-2016-Microprojects/), which seems easy for me.

I greped the source code and found out that there are two places where "git-credential-cache" are hard-coded:

1. credential-cache.c
2. contrib/persistent-https/socket.go
At first sight, there are following tasks to do:
1. implement a function `xdg_cache_home` similar to `xdg_config_home`
in `path.c`.
2. replace the hard-coded path with an call to `xdg_cache_home`.
I'm still confused about following:
1. should `~/.git-credential-cache` been moved to
`~/.cache/git/credential`(as the descreption of the micropject says)
or `~/.config/git/credential`(as the title of the microproject says)?
2. If `~/.cache/git/credential` is the desired target, there seems
nothing to do with `XDG_CONFIG_HOME`.
3. Does "without breaking compatibility with the old behavior." mean
that I should still try to connect to the unix socket placed at the
old place? If yes, which order is prefered?

Thanks for your patience. I hope that my English didn't affect the communication.

Junio C Hamano· Mar 14, 2016, 15:42 UTC · re: 惠轶群 · lore

Re: [GSOC] Microproject "Move ~/.git-credential-cache to ~/.config/git"

惠轶群 <huiyiqun@gmail.com> writes:
Show 5 quoted lines
> I'm still confused about following:
>
> 1. should `~/.git-credential-cache` been moved to
> `~/.cache/git/credential`(as the descreption of the micropject says)
> or `~/.config/git/credential`(as the title of the microproject says)?

The latter, I'd think, as you noticed in 2. the former does not make much sense.

> 2. If `~/.cache/git/credential` is the desired target, there seems
> nothing to do with `XDG_CONFIG_HOME`.

Yes, I think the intent of the problem specification is "if it is found in the XDG_CONFIG_HOME use $XDG_CONFIG_HOME/.config/git/* a the location to place it; by the way if the user does not have anything to explicitly say she wants to use a specific location for XDG_CONFIG_HOME, it defaults to "~/.config, hence the Git specific location becomes ~/.config/git/*".

> 3. Does "without breaking compatibility with the old behavior." mean
> that I should still try to connect to the unix socket placed at the
> old place? If yes, which order is prefered?
Let me be vague and oblique on purpose ;-)

We used to have only ~/.gitconfig as the per-user location, and at some point in the history we added XDG_CONFIG_HOME support. Study how that was done (hint: "git log" and "git blame" may be useful tools for this purpose), and imitate it.

惠轶群· Mar 14, 2016, 19:53 UTC · re: Junio C Hamano · lore

Re: [GSOC] Microproject "Move ~/.git-credential-cache to ~/.config/git"

2016-03-14 23:42 GMT+08:00 Junio C Hamano <gitster@pobox.com>:
Show 10 quoted lines
> 惠轶群 <huiyiqun@gmail.com> writes:
>
>> I'm still confused about following:
>>
>> 1. should `~/.git-credential-cache` been moved to
>> `~/.cache/git/credential`(as the descreption of the micropject says)
>> or `~/.config/git/credential`(as the title of the microproject says)?
>
> The latter, I'd think, as you noticed in 2. the former does not make
> much sense.

I'm not sure. There is only a unix socket under ~/.git-credential-cache. It's not a config.

After reading the [spec](https://specifications.freedesktop.org/basedir-spec/basedir-spec-0.7.html) more carefully, I think that $XDG_RUNTIME_DIR may be a better choice than the above two. For ~/.git-credential-cache/socket is a unix socket and should be used only runtime.

On my computer, this variable is well defined and pointed to /run/user/$UID.

The problem is that there is no suitable default to it if $XDG_RUNTIME_DIR is not set. I guess /tmp/git-$USER is a good choice.

Show 11 quoted lines
>> 3. Does "without breaking compatibility with the old behavior." mean
>> that I should still try to connect to the unix socket placed at the
>> old place? If yes, which order is prefered?
>
> Let me be vague and oblique on purpose ;-)
>
> We used to have only ~/.gitconfig as the per-user location, and at
> some point in the history we added XDG_CONFIG_HOME support.  Study
> how that was done (hint: "git log" and "git blame" may be useful
> tools for this purpose), and imitate it.
>
I have read almost every commit which contains "XDG", as well as their diffs.

I think this issue I'm currently dealing with is a little different from formers, For this file is just an unix socket and never persistent. I could not just keep in step with old behavior unless that user manually create the file at new-style path.

Of course I could check the existence of `~/.git-credential-cache` and `$XDG_CONFIG_HOME/git/credential-cache` to decide where to put the socket, but it's not elegant enough. Because, as mentioned above, the socket file itself is not persistent.

Junio C Hamano· Mar 14, 2016, 20:33 UTC · re: 惠轶群 · lore

Re: [GSOC] Microproject "Move ~/.git-credential-cache to ~/.config/git"

惠轶群 <huiyiqun@gmail.com> writes:
Show 5 quoted lines
> After reading the
> [spec](https://specifications.freedesktop.org/basedir-spec/basedir-spec-0.7.html)
> more carefully, I think that $XDG_RUNTIME_DIR may be a better choice than
> the above two. For ~/.git-credential-cache/socket is a unix socket and should
> be used only runtime.
Nice.
> Of course I could check the existence of `~/.git-credential-cache` and
> `$XDG_CONFIG_HOME/git/credential-cache` to decide where to put
> the socket,

I think that is the most sensible. They are directories that are expected to be persistent, aren't they?

You sound like you think it is better to check the location of the existing socket, but I am having a hard time understanding and/or guessing why you might think so, especially when you already know that the socket itself may not be persistent. Puzzled...

惠轶群· Mar 15, 2016, 01:32 UTC · re: Junio C Hamano · lore

Re: [GSOC] Microproject "Move ~/.git-credential-cache to ~/.config/git"

> You sound like you think it is better to check the location of the
> existing socket,
Yes, for the purpose of compatibility, it's the only choice, as I can see.
To sum up, I'd like to implement:
1. <path> is configured by --socket, then put it here.
2. else if `~/.git-credential-cache` exists, put the socket under here.
3. else, put the socket under
`$XDG_RUNTIME_DIR/git/credential-cache.sock`,
if $XDG_RUNTIME_DIR does not exist, default to
`/tmp/git-$UID/credential-cache.sock`.

As a result, new user will use xdg-compatible path while old user will not be surprised.

Your friend· Mar 15, 2016, 02:14 UTC · re: 惠轶群 · lore

Re: [GSOC] Microproject "Move ~/.git-credential-cache to ~/.config/git"

On 15/03/2016 09:32, 惠轶群 wrote:
Show 22 quoted lines
>> You sound like you think it is better to check the location of the
>> existing socket,
> 
> Yes, for the purpose of compatibility, it's the only choice, as I can 
> see.
> 
> To sum up, I'd like to implement:
> 
> 1. <path> is configured by --socket, then put it here.
> 2. else if `~/.git-credential-cache` exists, put the socket under here.
> 3. else, put the socket under
> `$XDG_RUNTIME_DIR/git/credential-cache.sock`,
> if $XDG_RUNTIME_DIR does not exist, default to
> `/tmp/git-$UID/credential-cache.sock`.
> 
> As a result, new user will use xdg-compatible path while old user will 
> not
> be surprised.
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

Hi, I am Ivan Tham 谭俊浩, I know a bit of C and more in python, I am currently taking foundation in a Asia Pacific University.

I would really like to work on this microproject for gsoc too but too bad 惠轶群 had taken it. :(

I think it should be in ~/$XDG_CACHE_HOME/git/credential or ~/.cache/git/credential instead of ~/.config/git/credential.

Jeff King· Mar 15, 2016, 03:13 UTC · re: 惠轶群 · lore

Re: [GSOC] Microproject "Move ~/.git-credential-cache to ~/.config/git"

On Tue, Mar 15, 2016 at 09:32:21AM +0800, 惠轶群 wrote:
> > You sound like you think it is better to check the location of the
> > existing socket,
> 
> Yes, for the purpose of compatibility, it's the only choice, as I can see.

I'm not sure the existing socket location matters, in the way that it does for config. The socket is inherently ephemeral, and designed to go away after a few minutes (and the program designed to run sanely when it does not exist).

So yes, when you switch from older git to newer git, you might technically have a cache-daemon running that you _could_ contact, but don't find it. But I don't think it's a big deal in practice, and not worth designing around.

So I think it would be OK to just switch the default path to wherever XDG recommends ephemeral stuff to go (which sounds like $XDG_RUNTIME_DIR) and be done.

-Peff
Hui Yiqun· Mar 16, 2016, 10:07 UTC · re: 惠轶群 · lore

[PATCH/RFC/GSoC 1/3] path.c: implement xdg_runtime_dir()

this function does the following:
1. if $XDG_RUNTIME_DIR is non-empty, `$XDG_RUNTIME_DIR/git` is used in next
step, otherwise `/tmp/git-$uid` is taken.
2. ensure that above directory does exist. what's more, it must has correct
permission and ownership.
3. a newly allocated string consisting of the path of above directory and
$filename is returned.
Under following situation, NULL will be returned:
+ the directory mentioned in step 1 exists but have wrong permission or
ownership.
+ the directory or its parent cannot be created.
Notice:
+ the caller is responsible for deallocating the returned string.
Signed-off-by: Hui Yiqun <huiyiqun@gmail.com>
---
 cache.h | 23 +++++++++++++++++++++++
 path.c  | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 82 insertions(+)
diff --git a/cache.h b/cache.h
index b829410..e640a54 100644
--- a/cache.h
+++ b/cache.h
@@ -999,6 +999,29 @@ extern int is_ntfs_dotgit(const char *name);
  */
 extern char *xdg_config_home(const char *filename);
 
+/**
+ * this function does the following:
+ *
+ * 1. if $XDG_RUNTIME_DIR is non-empty, `$XDG_RUNTIME_DIR/git` is used in next
+ * step, otherwise `/tmp/git-$uid` is taken.
+ * 2. ensure that above directory does exist. what's more, it must has correct
+ * permission and ownership.
+ * 3. a newly allocated string consisting of the path of above directory and
+ * $filename is returned.
+ *
+ * Under following situation, NULL will be returned:
+ *
+ * + the directory mentioned in step 1 exists but have wrong permission or
+ * ownership.
+ * + the directory or its parent cannot be created.
+ *
+ * Notice:
+ *
+ * + the caller is responsible for deallocating the returned string.
+ *
+ */
+extern char *xdg_runtime_dir(const char *filename);
+
 /* object replacement */
 #define LOOKUP_REPLACE_OBJECT 1
 #define LOOKUP_UNKNOWN_OBJECT 2
diff --git a/path.c b/path.c
index 8b7e168..2deecb3 100644
--- a/path.c
+++ b/path.c
@@ -5,6 +5,7 @@
 #include "strbuf.h"
 #include "string-list.h"
 #include "dir.h"
+#include "git-compat-util.h"
 
 static int get_st_mode_bits(const char *path, int *mode)
 {
@@ -1193,6 +1194,64 @@ char *xdg_config_home(const char *filename)
 	return NULL;
 }
 
+char *xdg_runtime_dir(const char *filename)
+{
+	char *runtime_dir, *git_runtime_dir;
+	struct stat st;
+	uid_t uid = getuid();
+
+	assert(filename);
+	runtime_dir = getenv("XDG_RUNTIME_DIR");
+	if (runtime_dir && *runtime_dir)
+		git_runtime_dir = mkpathdup("%s/git/", runtime_dir);
+	else
+		git_runtime_dir = mkpathdup("/tmp/git-%d", uid);
+
+	if (!lstat(git_runtime_dir, &st)) {
+		/*
+		 * As described in XDG base dir spec[1], the subdirectory
+		 * under $XDG_RUNTIME_DIR or its fallback MUST be owned by
+		 * the user, and its unix access mode MUST be 0700.
+		 *
+		 * Calling chmod or chown silently may cause security
+		 * problem if somebody chdir to it, sleep, and then, try
+		 * to open our protected runtime cache or socket.
+		 * So we just put warning and left it to user to solve.
+		 *
+		 * [1]https://specifications.freedesktop.org/basedir-spec/
+		 * basedir-spec-latest.html
+		 */
+		if ((st.st_mode & 0777) != S_IRWXU) {
+			fprintf(stderr,
+					"permission of runtime directory '%s' "
+					"MUST be 0700 instead of 0%o\n",
+					git_runtime_dir, (st.st_mode & 0777));
+			return NULL;
+		} else if (st.st_uid != uid) {
+			fprintf(stderr,
+					"owner of runtime directory '%s' "
+					"MUST be %d instead of %d\n",
+					git_runtime_dir, uid, st.st_uid);
+			return NULL;
+		}
+		/* TODO: check whether git_runtime_dir is an directory */
+	} else {
+		if (safe_create_leading_directories_const(git_runtime_dir) < 0) {
+			fprintf(stderr,
+					"unable to create directories for '%s'\n",
+					git_runtime_dir);
+			return NULL;
+		}
+		if (mkdir(git_runtime_dir, 0700) < 0) {
+			fprintf(stderr,
+					"unable to mkdir '%s'\n", git_runtime_dir);
+			return NULL;
+		}
+	}
+	free(git_runtime_dir);
+	return mkpathdup("%s/%s", git_runtime_dir, filename);
+}
+
 GIT_PATH_FUNC(git_path_cherry_pick_head, "CHERRY_PICK_HEAD")
 GIT_PATH_FUNC(git_path_revert_head, "REVERT_HEAD")
 GIT_PATH_FUNC(git_path_squash_msg, "SQUASH_MSG")
-- 
2.7.2
Hui Yiqun· Mar 16, 2016, 10:07 UTC · re: Hui Yiqun · lore

[PATCH/RFC/GSoC 2/3] git-credential-cache: put socket to xdg-compatible path

move .git-credential-cache/socket to xdg_runtime_dir("credential-cache.sock")
Signed-off-by: Hui Yiqun <huiyiqun@gmail.com>
---
 credential-cache.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/credential-cache.c b/credential-cache.c
index f4afdc6..40d838b 100644
--- a/credential-cache.c
+++ b/credential-cache.c
@@ -105,7 +105,7 @@ int main(int argc, const char **argv)
 	op = argv[0];
 
 	if (!socket_path)
-		socket_path = expand_user_path("~/.git-credential-cache/socket");
+		socket_path = xdg_runtime_dir("credential-cache.sock");
 	if (!socket_path)
 		die("unable to find a suitable socket path; use --socket");
 
-- 
2.7.2
惠轶群· Mar 17, 2016, 10:26 UTC · re: Hui Yiqun · lore

Re: [PATCH/RFC/GSoC 2/3] git-credential-cache: put socket to xdg-compatible path

2016-03-16 18:07 GMT+08:00 Hui Yiqun <huiyiqun@gmail.com>:
Show 23 quoted lines
> move .git-credential-cache/socket to xdg_runtime_dir("credential-cache.sock")
>
> Signed-off-by: Hui Yiqun <huiyiqun@gmail.com>
> ---
>  credential-cache.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/credential-cache.c b/credential-cache.c
> index f4afdc6..40d838b 100644
> --- a/credential-cache.c
> +++ b/credential-cache.c
> @@ -105,7 +105,7 @@ int main(int argc, const char **argv)
>         op = argv[0];
>
>         if (!socket_path)
> -               socket_path = expand_user_path("~/.git-credential-cache/socket");
> +               socket_path = xdg_runtime_dir("credential-cache.sock");
>         if (!socket_path)
>                 die("unable to find a suitable socket path; use --socket");
>
> --
> 2.7.2
>
I'm sure but if user set up git-credential-cache with following command:
    git config --global credential.helper "cache --socket
~/.git-credential-cache/socket"
will the ~ be expanded?
Hui Yiqun· Mar 16, 2016, 10:07 UTC · re: Hui Yiqun · lore

[PATCH/RFC/GSoC 3/3] t0301: test credential-cache support of XDG_RUNTIME_DIR

t0301 now tests git-credential-cache support for XDG user-specific runtime file $XDG_RUNTIME_DIR/git/credential.sock. Specifically:

* if $XDG_RUNTIME_DIR exists, use socket at
  `$XDG_RUNTIME_DIR/git/credential-cache.sock`.
* otherwise, `/tmp/git-$uid/credential-cache.sock` is taken.
Signed-off-by: Hui Yiqun <huiyiqun@gmail.com>
---
 t/t0301-credential-cache.sh | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)
diff --git a/t/t0301-credential-cache.sh b/t/t0301-credential-cache.sh
index 82c8411..0718bb0 100755
--- a/t/t0301-credential-cache.sh
+++ b/t/t0301-credential-cache.sh
@@ -12,7 +12,32 @@ test -z "$NO_UNIX_SOCKETS" || {
 # don't leave a stale daemon running
 trap 'code=$?; git credential-cache exit; (exit $code); die' EXIT
 
+test_expect_success 'set $XDG_RUNTIME_DIR' '
+	XDG_RUNTIME_DIR=$HOME/xdg_runtime/
+'
+
+helper_test cache
+
+test_expect_success 'when $XDG_RUNTIME_DIR is set, `$XDG_RUNTIME_DIR/git` are used' '
+	test_path_is_missing "/tmp/git-$(id -u)/git/credential-cache.sock" &&
+	test -S "$XDG_RUNTIME_DIR/git/credential-cache.sock"
+'
+
+test_expect_success 'force git-credential-cache to exit so that socket disappear' '
+	git credential-cache exit &&
+	test_path_is_missing "$XDG_RUNTIME_DIR/git/credential-cache.sock" &&
+	unset XDG_RUNTIME_DIR
+'
+
 helper_test cache
+
+test_expect_success 'when $XDG_RUNTIME_DIR is not set, `/tmp/git-$(id -u) is used' '
+	test -S "/tmp/git-$(id -u)/credential-cache.sock"
+'
+
+# TODO: if $XDG_RUNTIME_DIR/git/ exists, but has wrong permission and ownership,
+# `helper_test cache` must fail.
+
 helper_test_timeout cache --timeout=1
 
 # we can't rely on our "trap" above working after test_done,
-- 
2.7.2
Junio C Hamano· Mar 16, 2016, 16:17 UTC · re: Hui Yiqun · lore

Re: [PATCH/RFC/GSoC 3/3] t0301: test credential-cache support of XDG_RUNTIME_DIR

Hui Yiqun <huiyiqun@gmail.com> writes:
Show 7 quoted lines
> t0301 now tests git-credential-cache support for XDG user-specific
> runtime file $XDG_RUNTIME_DIR/git/credential.sock. Specifically:
>
> * if $XDG_RUNTIME_DIR exists, use socket at
>   `$XDG_RUNTIME_DIR/git/credential-cache.sock`.
>
> * otherwise, `/tmp/git-$uid/credential-cache.sock` is taken.

Is it better to have the fallback in /tmp, and not in ~/.git-credential-cache/, and why?

Is it because the wish is to always use /tmp/git-$uid/ as a fallback for $XDG_RUNTIME_DIR (as opposed to ~/.git-credential-cache/, which is specific to the credential-cache and would look strange if we used it for other "runtime" things)?

Just being curious, and wanting to see the reasoning behind the design decision the patch series makes in the log message of one of these patches.

Thanks.
惠轶群· Mar 16, 2016, 16:40 UTC · re: Junio C Hamano · lore

Re: [PATCH/RFC/GSoC 3/3] t0301: test credential-cache support of XDG_RUNTIME_DIR

2016-03-17 0:17 GMT+08:00 Junio C Hamano <gitster@pobox.com>:
Show 17 quoted lines
> Hui Yiqun <huiyiqun@gmail.com> writes:
>
>> t0301 now tests git-credential-cache support for XDG user-specific
>> runtime file $XDG_RUNTIME_DIR/git/credential.sock. Specifically:
>>
>> * if $XDG_RUNTIME_DIR exists, use socket at
>>   `$XDG_RUNTIME_DIR/git/credential-cache.sock`.
>>
>> * otherwise, `/tmp/git-$uid/credential-cache.sock` is taken.
>
> Is it better to have the fallback in /tmp, and not in
> ~/.git-credential-cache/, and why?
>
> Is it because the wish is to always use /tmp/git-$uid/ as a fallback
> for $XDG_RUNTIME_DIR (as opposed to ~/.git-credential-cache/, which
> is specific to the credential-cache and would look strange if we
> used it for other "runtime" things)?
Yes, I mean to use it as a general fallback for git.

xdg base dir spec does not specify where to fallback when $XDG_RUNTIME_DIR is not defined. It just says:

If $XDG_RUNTIME_DIR is not set applications should fall back to a replacement directory with similar capabilities and print a warning message. Applications should use this directory for communication and synchronization purposes and should not place larger files in it, since it might reside in runtime memory and cannot necessarily be swapped out to disk.

tmpfs is just like what it describes. And many other applications put socket under which, such as tmux.

On the other hand, I think, falling back to $HOME/.git-credential-cache/socket doesn't make any sense for back-compability cannot be ensured.

Show 7 quoted lines
>
> Just being curious, and wanting to see the reasoning behind the
> design decision the patch series makes in the log message of one of
> these patches.
>
> Thanks.
>
Jeff King· Mar 16, 2016, 16:55 UTC · re: 惠轶群 · lore

Re: [PATCH/RFC/GSoC 3/3] t0301: test credential-cache support of XDG_RUNTIME_DIR

On Thu, Mar 17, 2016 at 12:40:59AM +0800, 惠轶群 wrote:
Show 25 quoted lines
> > Is it better to have the fallback in /tmp, and not in
> > ~/.git-credential-cache/, and why?
> >
> > Is it because the wish is to always use /tmp/git-$uid/ as a fallback
> > for $XDG_RUNTIME_DIR (as opposed to ~/.git-credential-cache/, which
> > is specific to the credential-cache and would look strange if we
> > used it for other "runtime" things)?
> 
> Yes, I mean to use it as a general fallback for git.
> 
> xdg base dir spec does not specify where to fallback when
> $XDG_RUNTIME_DIR is not defined. It just says:
> 
> If $XDG_RUNTIME_DIR is not set applications should fall back to
> a replacement directory with similar capabilities and print a warning
> message. Applications should use this directory for communication
> and synchronization purposes and should not place larger files in it,
> since it might reside in runtime memory and cannot necessarily be
> swapped out to disk.
> 
> tmpfs is just like what it describes. And many other applications
> put socket under which, such as tmux.
> 
> On the other hand, I think, falling back to $HOME/.git-credential-cache/socket
> doesn't make any sense for back-compability cannot be ensured.

If we are going to use a publicly accessible directory like /tmp, I think we need to start worrying about tmp-races with malicious users.

Right now we make sure that an existing socket directory is mode 0700. That's just a courtesy check that the user didn't create it themselves with a permissive mode. But we don't check the owner of the directory, and our check is racy with accessing the directory.

So if we blindly use an existing /tmp/git-$uid, I think an attacker can race with:

    dir=/tmp/git-$victimuid
    mkdir $dir
    while true; do
        chmod 0700 $dir
	chmod 0777 $dir
    done

If the victim does their mode check while the 0700 is in effect, but then creates the socket during the 0777 moment, they won't notice anything amiss. And the attacker will have access to their credential socket.

This is a classic /tmp race. I imagine it's less of an issue in this day and age when people mostly have their own machines and their own /tmp, but we still should not recreate the mistakes of the past.

-Peff
Junio C Hamano· Mar 16, 2016, 17:24 UTC · re: 惠轶群 · lore

Re: [PATCH/RFC/GSoC 3/3] t0301: test credential-cache support of XDG_RUNTIME_DIR

惠轶群 <huiyiqun@gmail.com> writes:
Show 6 quoted lines
>> Is it because the wish is to always use /tmp/git-$uid/ as a fallback
>> for $XDG_RUNTIME_DIR (as opposed to ~/.git-credential-cache/, which
>> is specific to the credential-cache and would look strange if we
>> used it for other "runtime" things)?
>
> Yes, I mean to use it as a general fallback for git.

If that is the case the code probably needs to be a bit more careful before deciding to use /tmp/git-$uid/ directory (is it really $uid's? can anybody else write to it to race with the real user? etc.)

> On the other hand, I think, falling back to $HOME/.git-credential-cache/socket
> doesn't make any sense for back-compability cannot be ensured.
What do you mean by that?

Using ~/.git-credential-cache/credential-cache.sock would not help at all for existing users, but ~/.git-credential-cache/socket would interoperate well with users with existing versions of Git, no?

>> Just being curious, and wanting to see the reasoning behind the
>> design decision the patch series makes in the log message of one of
>> these patches.
谭俊浩· Mar 17, 2016, 03:59 UTC · re: Junio C Hamano · lore

Re: [PATCH/RFC/GSoC 3/3] t0301: test credential-cache support of XDG_RUNTIME_DIR

On 17/03/2016 01:24, Junio C Hamano wrote:
Show 26 quoted lines
> 惠轶群 <huiyiqun@gmail.com> writes:
> 
>>> Is it because the wish is to always use /tmp/git-$uid/ as a fallback
>>> for $XDG_RUNTIME_DIR (as opposed to ~/.git-credential-cache/, which
>>> is specific to the credential-cache and would look strange if we
>>> used it for other "runtime" things)?
>> 
>> Yes, I mean to use it as a general fallback for git.
> 
> If that is the case the code probably needs to be a bit more careful
> before deciding to use /tmp/git-$uid/ directory (is it really $uid's?
> can anybody else write to it to race with the real user? etc.)
> 
>> On the other hand, I think, falling back to 
>> $HOME/.git-credential-cache/socket
>> doesn't make any sense for back-compability cannot be ensured.
> 
> What do you mean by that?
> 
> Using ~/.git-credential-cache/credential-cache.sock would not help
> at all for existing users, but ~/.git-credential-cache/socket would
> interoperate well with users with existing versions of Git, no?
> 
>>> Just being curious, and wanting to see the reasoning behind the
>>> design decision the patch series makes in the log message of one of
>>> these patches.

I guess it is better to use /tmp or such instead of $HOME/.* so that the users home directory won't be flooded by sockets.

Junio C Hamano· Mar 17, 2016, 08:12 UTC · re: 谭俊浩 · lore

Re: [PATCH/RFC/GSoC 3/3] t0301: test credential-cache support of XDG_RUNTIME_DIR

谭俊浩 <pickfire@riseup.net> writes:
Show 12 quoted lines
> On 17/03/2016 01:24, Junio C Hamano wrote:
>
>> Using ~/.git-credential-cache/credential-cache.sock would not help
>> at all for existing users, but ~/.git-credential-cache/socket would
>> interoperate well with users with existing versions of Git, no?
>>
>>>> Just being curious, and wanting to see the reasoning behind the
>>>> design decision the patch series makes in the log message of one of
>>>> these patches.
>
> I guess it is better to use /tmp or such instead of $HOME/.* so that
> the users home directory won't be flooded by sockets.

The "fallback" being discussed is to see if $XDG can be used (and use it if so), otherwise see if ~/.git-credential-cache/socket can be used (and use it if so), otherwise die with a message (see credential-cache.c). The order of the falling back may want to be the other way around, but in either case, the definition of "can be used" includes "is there already a directory in which we can create a socket?".

The existing versions have used ~/.git-credential-cache/socket as the default socket path, so it is reasonable to expect that users that are already using the feature already have the directory there.

So I do not think there is any "flooded" involved; if the directory is already there, we can use it to create and use a single socket. It's not like we'd be creating many random new directories in ~/.

惠轶群· Mar 17, 2016, 10:10 UTC · re: Junio C Hamano · lore

Re: [PATCH/RFC/GSoC 3/3] t0301: test credential-cache support of XDG_RUNTIME_DIR

2016-03-17 16:12 GMT+08:00 Junio C Hamano <gitster@pobox.com>:
Show 30 quoted lines
> 谭俊浩 <pickfire@riseup.net> writes:
>
>> On 17/03/2016 01:24, Junio C Hamano wrote:
>>
>>> Using ~/.git-credential-cache/credential-cache.sock would not help
>>> at all for existing users, but ~/.git-credential-cache/socket would
>>> interoperate well with users with existing versions of Git, no?
>>>
>>>>> Just being curious, and wanting to see the reasoning behind the
>>>>> design decision the patch series makes in the log message of one of
>>>>> these patches.
>>
>> I guess it is better to use /tmp or such instead of $HOME/.* so that
>> the users home directory won't be flooded by sockets.
>
> The "fallback" being discussed is to see if $XDG can be used (and
> use it if so), otherwise see if ~/.git-credential-cache/socket can
> be used (and use it if so), otherwise die with a message (see
> credential-cache.c).  The order of the falling back may want to be
> the other way around, but in either case, the definition of "can be
> used" includes "is there already a directory in which we can create
> a socket?".
>
> The existing versions have used ~/.git-credential-cache/socket as
> the default socket path, so it is reasonable to expect that users
> that are already using the feature already have the directory there.
>
> So I do not think there is any "flooded" involved; if the directory
> is already there, we can use it to create and use a single socket.
> It's not like we'd be creating many random new directories in ~/.

As mentioned above, The purpose I try "$XDG_RUNTIME_DIR" and then "/tmp/git-$uid" is that I'd like to build an identical mechanism for searching for path to store runtime files such as socket and so on.

I guess you would not second an additional configuration to let git store runtime files under XDG-compatible path.

Then is there any better solution to keep compatibility than checking the existence of ~/.git-credential-cache? I'm not sure.

I think we could left following message in documentation:
    From version xxx, we put the socket under a XDG-compatible path instead of
    a directory under $HOME. If that incompatibility disturbs you,
please consider
    adding `--socket $HOME/.git-credential-cache/socket` to your configuration.
惠轶群· Mar 17, 2016, 09:45 UTC · re: Junio C Hamano · lore

Re: [PATCH/RFC/GSoC 3/3] t0301: test credential-cache support of XDG_RUNTIME_DIR

2016-03-17 1:24 GMT+08:00 Junio C Hamano <gitster@pobox.com>:
Show 22 quoted lines
> 惠轶群 <huiyiqun@gmail.com> writes:
>
>>> Is it because the wish is to always use /tmp/git-$uid/ as a fallback
>>> for $XDG_RUNTIME_DIR (as opposed to ~/.git-credential-cache/, which
>>> is specific to the credential-cache and would look strange if we
>>> used it for other "runtime" things)?
>>
>> Yes, I mean to use it as a general fallback for git.
>
> If that is the case the code probably needs to be a bit more careful
> before deciding to use /tmp/git-$uid/ directory (is it really $uid's?
> can anybody else write to it to race with the real user? etc.)
>
>> On the other hand, I think, falling back to $HOME/.git-credential-cache/socket
>> doesn't make any sense for back-compability cannot be ensured.
>
> What do you mean by that?
>
> Using ~/.git-credential-cache/credential-cache.sock would not help
> at all for existing users, but ~/.git-credential-cache/socket would
> interoperate well with users with existing versions of Git, no?
>
I meant that FALLBACK instead of DEFAULT is useless for back-compatibility.

Most users with existing versions of Git will be broken even if there is a fallback.

Jeff King· Mar 16, 2016, 17:15 UTC · re: Hui Yiqun · lore

Re: [PATCH/RFC/GSoC 3/3] t0301: test credential-cache support of XDG_RUNTIME_DIR

On Wed, Mar 16, 2016 at 06:07:45PM +0800, Hui Yiqun wrote:
Show 11 quoted lines
> diff --git a/t/t0301-credential-cache.sh b/t/t0301-credential-cache.sh
> index 82c8411..0718bb0 100755
> --- a/t/t0301-credential-cache.sh
> +++ b/t/t0301-credential-cache.sh
> @@ -12,7 +12,32 @@ test -z "$NO_UNIX_SOCKETS" || {
>  # don't leave a stale daemon running
>  trap 'code=$?; git credential-cache exit; (exit $code); die' EXIT
>  
> +test_expect_success 'set $XDG_RUNTIME_DIR' '
> +	XDG_RUNTIME_DIR=$HOME/xdg_runtime/
> +'

Doesn't this need to export the variable so that credential-cache can see it?

> +
> +helper_test cache
> +

This runs the full suite of tests twice (once here, and once for the original helper_test invocation you left below). Shouldn't we just do it once (making sure that $XDG_RUNTIME_DIR is respected)?

Show 5 quoted lines
> +test_expect_success 'force git-credential-cache to exit so that socket disappear' '
> +	git credential-cache exit &&
> +	test_path_is_missing "$XDG_RUNTIME_DIR/git/credential-cache.sock" &&
> +	unset XDG_RUNTIME_DIR
> +'

I wondered if this might be racy. credential-cache tells the daemon "exit", then waits for a response or EOF. The daemon sees "exit" and calls exit(0) immediately. We clean up the socket in an atexit() handler. So I think we are OK (the pipe will get closed when the process exits, and the atexit handler must have run by then).

But that definitely was not designed, and is just how it happens to work. I'm not sure if it's worth commenting on that (here, or perhaps in the daemon code).

-Peff
惠轶群· Mar 18, 2016, 04:35 UTC · re: Jeff King · lore

Re: [PATCH/RFC/GSoC 3/3] t0301: test credential-cache support of XDG_RUNTIME_DIR

2016-03-17 1:15 GMT+08:00 Jeff King <peff@peff.net>:
Show 16 quoted lines
> On Wed, Mar 16, 2016 at 06:07:45PM +0800, Hui Yiqun wrote:
>
>> diff --git a/t/t0301-credential-cache.sh b/t/t0301-credential-cache.sh
>> index 82c8411..0718bb0 100755
>> --- a/t/t0301-credential-cache.sh
>> +++ b/t/t0301-credential-cache.sh
>> @@ -12,7 +12,32 @@ test -z "$NO_UNIX_SOCKETS" || {
>>  # don't leave a stale daemon running
>>  trap 'code=$?; git credential-cache exit; (exit $code); die' EXIT
>>
>> +test_expect_success 'set $XDG_RUNTIME_DIR' '
>> +     XDG_RUNTIME_DIR=$HOME/xdg_runtime/
>> +'
>
> Doesn't this need to export the variable so that credential-cache can
> see it?

I'm not sure, but it seems that a little clean up code added before send-email make the test fail. At that time, I run test without building. I've send PATCH v2 which runs well on my computer. However, $XDG_RUNTIME_DIR is still not exported, but that just works.

I will try to dig deeper into the bash script to see why.
Show 8 quoted lines
>
>> +
>> +helper_test cache
>> +
>
> This runs the full suite of tests twice (once here, and once for the
> original helper_test invocation you left below). Shouldn't we just do it
> once (making sure that $XDG_RUNTIME_DIR is respected)?

I'd like to test the behavior of git-credential-cache when $XDG_RUNTIME_DIR is unset.

In `t/t0302-credential-store.sh`, helper_test is also run multiple times. That's why I do so.

Show 15 quoted lines
>> +test_expect_success 'force git-credential-cache to exit so that socket disappear' '
>> +     git credential-cache exit &&
>> +     test_path_is_missing "$XDG_RUNTIME_DIR/git/credential-cache.sock" &&
>> +     unset XDG_RUNTIME_DIR
>> +'
>
> I wondered if this might be racy. credential-cache tells the daemon
> "exit", then waits for a response or EOF. The daemon sees "exit" and
> calls exit(0) immediately. We clean up the socket in an atexit()
> handler. So I think we are OK (the pipe will get closed when the process
> exits, and the atexit handler must have run by then).
>
> But that definitely was not designed, and is just how it happens to
> work. I'm not sure if it's worth commenting on that (here, or perhaps in
> the daemon code).
I'm still confused.
What do you mean by "pipe"? should it be "socket" instead?

What is not designed? cleanup being done, my tests passing or the synchronization?

>
> -Pef
Jeff King· Mar 16, 2016, 17:06 UTC · re: Hui Yiqun · lore

Re: [PATCH/RFC/GSoC 1/3] path.c: implement xdg_runtime_dir()

On Wed, Mar 16, 2016 at 06:07:43PM +0800, Hui Yiqun wrote:
> +	if (runtime_dir && *runtime_dir)
> +		git_runtime_dir = mkpathdup("%s/git/", runtime_dir);
> +	else
> +		git_runtime_dir = mkpathdup("/tmp/git-%d", uid);

Here we allocate the string, but later we may return NULL on error, leaking the allocated memory.

Show 14 quoted lines
> +	if (!lstat(git_runtime_dir, &st)) {
> +		/*
> +		 * As described in XDG base dir spec[1], the subdirectory
> +		 * under $XDG_RUNTIME_DIR or its fallback MUST be owned by
> +		 * the user, and its unix access mode MUST be 0700.
> +		 *
> +		 * Calling chmod or chown silently may cause security
> +		 * problem if somebody chdir to it, sleep, and then, try
> +		 * to open our protected runtime cache or socket.
> +		 * So we just put warning and left it to user to solve.
> +		 *
> +		 * [1]https://specifications.freedesktop.org/basedir-spec/
> +		 * basedir-spec-latest.html
> +		 */

OK. I think these checks should be sufficient to deal with the /tmp race I mentioned elsewhere in the thread (assuming that an attacker cannot flip the uid back and forth in the same way, but that should be true on Unix systems).

Show 13 quoted lines
> +		if ((st.st_mode & 0777) != S_IRWXU) {
> +			fprintf(stderr,
> +					"permission of runtime directory '%s' "
> +					"MUST be 0700 instead of 0%o\n",
> +					git_runtime_dir, (st.st_mode & 0777));
> +			return NULL;
> +		} else if (st.st_uid != uid) {
> +			fprintf(stderr,
> +					"owner of runtime directory '%s' "
> +					"MUST be %d instead of %d\n",
> +					git_runtime_dir, uid, st.st_uid);
> +			return NULL;
> +		}
Should these be using warning(), rather than a raw fprintf?
Show 13 quoted lines
> +	} else {
> +		if (safe_create_leading_directories_const(git_runtime_dir) < 0) {
> +			fprintf(stderr,
> +					"unable to create directories for '%s'\n",
> +					git_runtime_dir);
> +			return NULL;
> +		}
> +		if (mkdir(git_runtime_dir, 0700) < 0) {
> +			fprintf(stderr,
> +					"unable to mkdir '%s'\n", git_runtime_dir);
> +			return NULL;
> +		}
> +	}
And this retains the un-racy mkdir(). Good.
> +	free(git_runtime_dir);
> +	return mkpathdup("%s/%s", git_runtime_dir, filename);
This mkpathdup accesses the string we just freed?

It might be easier to just use a strbuf here, and then you can append to it at the end.

-Peff
惠轶群· Mar 17, 2016, 10:20 UTC · re: Jeff King · lore

Re: [PATCH/RFC/GSoC 1/3] path.c: implement xdg_runtime_dir()

2016-03-17 1:06 GMT+08:00 Jeff King <peff@peff.net>:
Show 9 quoted lines
> On Wed, Mar 16, 2016 at 06:07:43PM +0800, Hui Yiqun wrote:
>
>> +     if (runtime_dir && *runtime_dir)
>> +             git_runtime_dir = mkpathdup("%s/git/", runtime_dir);
>> +     else
>> +             git_runtime_dir = mkpathdup("/tmp/git-%d", uid);
>
> Here we allocate the string, but later we may return NULL on error,
> leaking the allocated memory.
Yes, do you think goto is a good solution for clearup?
Show 36 quoted lines
>
>> +     if (!lstat(git_runtime_dir, &st)) {
>> +             /*
>> +              * As described in XDG base dir spec[1], the subdirectory
>> +              * under $XDG_RUNTIME_DIR or its fallback MUST be owned by
>> +              * the user, and its unix access mode MUST be 0700.
>> +              *
>> +              * Calling chmod or chown silently may cause security
>> +              * problem if somebody chdir to it, sleep, and then, try
>> +              * to open our protected runtime cache or socket.
>> +              * So we just put warning and left it to user to solve.
>> +              *
>> +              * [1]https://specifications.freedesktop.org/basedir-spec/
>> +              * basedir-spec-latest.html
>> +              */
>
> OK. I think these checks should be sufficient to deal with the /tmp race
> I mentioned elsewhere in the thread (assuming that an attacker cannot
> flip the uid back and forth in the same way, but that should be true on
> Unix systems).
>
>> +             if ((st.st_mode & 0777) != S_IRWXU) {
>> +                     fprintf(stderr,
>> +                                     "permission of runtime directory '%s' "
>> +                                     "MUST be 0700 instead of 0%o\n",
>> +                                     git_runtime_dir, (st.st_mode & 0777));
>> +                     return NULL;
>> +             } else if (st.st_uid != uid) {
>> +                     fprintf(stderr,
>> +                                     "owner of runtime directory '%s' "
>> +                                     "MUST be %d instead of %d\n",
>> +                                     git_runtime_dir, uid, st.st_uid);
>> +                     return NULL;
>> +             }
>
> Should these be using warning(), rather than a raw fprintf?
Well, I will replace it.

During the greping. I found that I should also wrap my warning strings with _() for i18n.

Show 24 quoted lines
>
>> +     } else {
>> +             if (safe_create_leading_directories_const(git_runtime_dir) < 0) {
>> +                     fprintf(stderr,
>> +                                     "unable to create directories for '%s'\n",
>> +                                     git_runtime_dir);
>> +                     return NULL;
>> +             }
>> +             if (mkdir(git_runtime_dir, 0700) < 0) {
>> +                     fprintf(stderr,
>> +                                     "unable to mkdir '%s'\n", git_runtime_dir);
>> +                     return NULL;
>> +             }
>> +     }
>
> And this retains the un-racy mkdir(). Good.
>
>> +     free(git_runtime_dir);
>> +     return mkpathdup("%s/%s", git_runtime_dir, filename);
>
> This mkpathdup accesses the string we just freed?
>
> It might be easier to just use a strbuf here, and then you can append to
> it at the end.
I think so. Thanks.
>
> -Peff
Ivan Tham· Mar 15, 2016, 05:56 UTC · lore

Re: [GSOC] Microproject "Move ~/.git-credential-cache to ~/.config/git"

On 15/03/2016 10:59, 惠轶群 wrote:
Show 10 quoted lines
> Well, In my opinion:
> 
> 1. $XDG_CACHE_HOME is more meaningful than $XDG_CONFIG_HOME,
> while $XDG_RUNTIME_DIR is more meaningful than $XDG_CACHE_HOME.
> However, I feel that I should value suggestions of who have more 
> experience
> about this project than me.
> 
> 2. $XDG_CACHE_HOME is absolute, so it's $XDG_CACHE_HOME/git/credential
> instead of ~/$XDG_CACHE_HOME/git/credential.

Oh, I guess now $XDG_RUNTIME_DIR is really most suitable for this after reading more about the XDG Standard.

Jeff King· Mar 15, 2016, 19:21 UTC · lore

Re: [GSOC] Microproject "Move ~/.git-credential-cache to ~/.config/git"

On Tue, Mar 15, 2016 at 05:48:18AM +0000, 惠轶群 wrote:
Show 14 quoted lines
> On Tue, Mar 15, 2016, 11:13 AM Jeff King <peff@peff.net> wrote:
> > The socket is inherently ephemeral, and designed to go
> > away after a few minutes (and the program designed to run sanely when it
> > does not exist).
> 
> I agree.
> 
> > So yes, when you switch from older git to newer git, you might
> > technically have a cache-daemon running that you _could_ contact, but
> > don't find it. But I don't think it's a big deal in practice, and not
> > worth designing around
> 
> Yes, it's OK with git itself. What I worry about is that this change break
> some third-party tools. Does it matter?

I don't think so. I suppose one could have a script that tests for the existence of the socket or something. But then, I don't think "use the old directory if it exists" really solves that. Such a script would work on people who had already run the old version of credential-cache, and break on new ones.

-Peff
惠轶群· Mar 16, 2016, 10:45 UTC · re: Jeff King · lore

Re: [GSOC] Microproject "Move ~/.git-credential-cache to ~/.config/git"

2016-03-16 3:21 GMT+08:00 Jeff King <peff@peff.net>:
> I don't think so. I suppose one could have a script that tests for the
> existence of the socket or something.
I agree, that is what I meant by "third-party tools".

But for user who write script like that, it's easy to figure out the problem and either update his/her scripts or explicitly declare the path of the socket in his gitconfig.

Anyway, most users will not be affected.
> But then, I don't think "use the
> old directory if it exists" really solves that. Such a script would work
> on people who had already run the old version of credential-cache, and
> break on new ones.

If back-compatibility must be ensured, the only graceful solution I can image is a new option entry like `xdg-style-path` being added to gitconfig and default it to false.

I doubt whether the increasing complexity is worthy just for the back-compatibilty of a socket path.

Jeff King· Mar 18, 2016, 05:00 UTC · lore

Re: [PATCH/RFC/GSoC 3/3] t0301: test credential-cache support of XDG_RUNTIME_DIR

On Fri, Mar 18, 2016 at 12:34:04PM +0800, 惠轶群 wrote:
Show 15 quoted lines
> >> +test_expect_success 'set $XDG_RUNTIME_DIR' '
> >> +     XDG_RUNTIME_DIR=$HOME/xdg_runtime/
> >> +'
> >
> > Doesn't this need to export the variable so that credential-cache can
> > see it?
> 
> I'm not sure, but it seems that a little clean up code added before
> send-email
> make the test fail. At that time, I run test without building. I've send
> PATCH v2
> which runs well on my computer. However, $XDG_RUNTIME_DIR is still not
> exported, but that just works.
> 
> I will try to dig deeper into the bash script to see why.

I suspect it is because you have $XDG_RUNTIME_DIR defined in your environment, which causes the shell to automatically export it. I don't, so an explicit "export" is required to for the variable to make it to its children.

I think we should actually be unsetting it in test-lib.sh for all tests, as we do for XDG_CONFIG_HOME. That makes sure the tests are running with a known state.

For the non-XDG_RUNTIME_DIR tests, does this mean we are creating the socket in /tmp? I'm not entirely happy with that, as we usually try to have the test suite avoid touching anything outside of its trash directories.

Show 9 quoted lines
> > This runs the full suite of tests twice (once here, and once for the
> > original helper_test invocation you left below). Shouldn't we just do it
> > once (making sure that $XDG_RUNTIME_DIR is respected)?
> 
> I'd like to test the behavior of git-credential-cache when $XDG_RUNTIME_DIR
> is unset.
> 
> In `t/t0302-credential-store.sh`, helper_test is also run multiple times.
> That's why I do so.

OK. My main concern was just that the tests would take too long, but the slow one is the cache test at the end, which is not repeated. So I think this is fine.

Show 13 quoted lines
> > I wondered if this might be racy. credential-cache tells the daemon
> > "exit", then waits for a response or EOF. The daemon sees "exit" and
> > calls exit(0) immediately. We clean up the socket in an atexit()
> > handler. So I think we are OK (the pipe will get closed when the process
> > exits, and the atexit handler must have run by then).
> >
> > But that definitely was not designed, and is just how it happens to
> > work. I'm not sure if it's worth commenting on that (here, or perhaps in
> > the daemon code).
> 
> I'm still confused.
> 
> What do you mean by "pipe"? should it be "socket" instead?
Sorry, yes, I used "pipe" and "socket" interchangeably there.
> What is not designed? cleanup being done, my tests passing or the
> synchronization?
The synchronization. If the daemon were implemented as:
  if (!strcmp(action.buf, "exit")) {
	/* acknowledge that we got command */
	fclose(out);
	exit(0);
  }

for example, then the client would exit at the same that the daemon is cleaning up the socket, and we may or may not call test_path_is_missing before the cleanup is done.

I think it's OK to rely on that, but we may want to put a comment to that effect in the daemon code so that it doesn't get changed.

-Peff
惠轶群· Mar 18, 2016, 05:11 UTC · re: Jeff King · lore

Re: [PATCH/RFC/GSoC 3/3] t0301: test credential-cache support of XDG_RUNTIME_DIR

2016-03-18 13:00 GMT+08:00 Jeff King <peff@peff.net>:
Show 22 quoted lines
> On Fri, Mar 18, 2016 at 12:34:04PM +0800, 惠轶群 wrote:
>
>> >> +test_expect_success 'set $XDG_RUNTIME_DIR' '
>> >> +     XDG_RUNTIME_DIR=$HOME/xdg_runtime/
>> >> +'
>> >
>> > Doesn't this need to export the variable so that credential-cache can
>> > see it?
>>
>> I'm not sure, but it seems that a little clean up code added before
>> send-email
>> make the test fail. At that time, I run test without building. I've send
>> PATCH v2
>> which runs well on my computer. However, $XDG_RUNTIME_DIR is still not
>> exported, but that just works.
>>
>> I will try to dig deeper into the bash script to see why.
>
> I suspect it is because you have $XDG_RUNTIME_DIR defined in your
> environment, which causes the shell to automatically export it. I don't,
> so an explicit "export" is required to for the variable to make it to
> its children.
Yes, that's the problem. the explicit "export" is new knowledge for me, thanks.
> I think we should actually be unsetting it in test-lib.sh for all tests,
> as we do for XDG_CONFIG_HOME. That makes sure the tests are running with
> a known state.
Well, I seems a good choice.
Show 52 quoted lines
> For the non-XDG_RUNTIME_DIR tests, does this mean we are creating the
> socket in /tmp? I'm not entirely happy with that, as we usually try to
> have the test suite avoid touching anything outside of its trash
> directories.
>
>> > This runs the full suite of tests twice (once here, and once for the
>> > original helper_test invocation you left below). Shouldn't we just do it
>> > once (making sure that $XDG_RUNTIME_DIR is respected)?
>>
>> I'd like to test the behavior of git-credential-cache when $XDG_RUNTIME_DIR
>> is unset.
>>
>> In `t/t0302-credential-store.sh`, helper_test is also run multiple times.
>> That's why I do so.
>
> OK. My main concern was just that the tests would take too long, but the
> slow one is the cache test at the end, which is not repeated. So I think
> this is fine.
>
>> > I wondered if this might be racy. credential-cache tells the daemon
>> > "exit", then waits for a response or EOF. The daemon sees "exit" and
>> > calls exit(0) immediately. We clean up the socket in an atexit()
>> > handler. So I think we are OK (the pipe will get closed when the process
>> > exits, and the atexit handler must have run by then).
>> >
>> > But that definitely was not designed, and is just how it happens to
>> > work. I'm not sure if it's worth commenting on that (here, or perhaps in
>> > the daemon code).
>>
>> I'm still confused.
>>
>> What do you mean by "pipe"? should it be "socket" instead?
>
> Sorry, yes, I used "pipe" and "socket" interchangeably there.
>
>> What is not designed? cleanup being done, my tests passing or the
>> synchronization?
>
> The synchronization. If the daemon were implemented as:
>
>   if (!strcmp(action.buf, "exit")) {
>         /* acknowledge that we got command */
>         fclose(out);
>         exit(0);
>   }
>
> for example, then the client would exit at the same that the daemon is
> cleaning up the socket, and we may or may not call test_path_is_missing
> before the cleanup is done.
>
> I think it's OK to rely on that, but we may want to put a comment to
> that effect in the daemon code so that it doesn't get changed.

The current implementation is natural for me. But having additional comment is better.

>
> -Peff
惠轶群· Mar 18, 2016, 06:02 UTC · re: 惠轶群 · lore

Re: [PATCH/RFC/GSoC 3/3] t0301: test credential-cache support of XDG_RUNTIME_DIR

2016-03-18 13:11 GMT+08:00 惠轶群 <huiyiqun@gmail.com>:
Show 87 quoted lines
> 2016-03-18 13:00 GMT+08:00 Jeff King <peff@peff.net>:
>> On Fri, Mar 18, 2016 at 12:34:04PM +0800, 惠轶群 wrote:
>>
>>> >> +test_expect_success 'set $XDG_RUNTIME_DIR' '
>>> >> +     XDG_RUNTIME_DIR=$HOME/xdg_runtime/
>>> >> +'
>>> >
>>> > Doesn't this need to export the variable so that credential-cache can
>>> > see it?
>>>
>>> I'm not sure, but it seems that a little clean up code added before
>>> send-email
>>> make the test fail. At that time, I run test without building. I've send
>>> PATCH v2
>>> which runs well on my computer. However, $XDG_RUNTIME_DIR is still not
>>> exported, but that just works.
>>>
>>> I will try to dig deeper into the bash script to see why.
>>
>> I suspect it is because you have $XDG_RUNTIME_DIR defined in your
>> environment, which causes the shell to automatically export it. I don't,
>> so an explicit "export" is required to for the variable to make it to
>> its children.
>
> Yes, that's the problem. the explicit "export" is new knowledge for me, thanks.
>
>> I think we should actually be unsetting it in test-lib.sh for all tests,
>> as we do for XDG_CONFIG_HOME. That makes sure the tests are running with
>> a known state.
>
> Well, I seems a good choice.
>
>> For the non-XDG_RUNTIME_DIR tests, does this mean we are creating the
>> socket in /tmp? I'm not entirely happy with that, as we usually try to
>> have the test suite avoid touching anything outside of its trash
>> directories.
>>
>>> > This runs the full suite of tests twice (once here, and once for the
>>> > original helper_test invocation you left below). Shouldn't we just do it
>>> > once (making sure that $XDG_RUNTIME_DIR is respected)?
>>>
>>> I'd like to test the behavior of git-credential-cache when $XDG_RUNTIME_DIR
>>> is unset.
>>>
>>> In `t/t0302-credential-store.sh`, helper_test is also run multiple times.
>>> That's why I do so.
>>
>> OK. My main concern was just that the tests would take too long, but the
>> slow one is the cache test at the end, which is not repeated. So I think
>> this is fine.
>>
>>> > I wondered if this might be racy. credential-cache tells the daemon
>>> > "exit", then waits for a response or EOF. The daemon sees "exit" and
>>> > calls exit(0) immediately. We clean up the socket in an atexit()
>>> > handler. So I think we are OK (the pipe will get closed when the process
>>> > exits, and the atexit handler must have run by then).
>>> >
>>> > But that definitely was not designed, and is just how it happens to
>>> > work. I'm not sure if it's worth commenting on that (here, or perhaps in
>>> > the daemon code).
>>>
>>> I'm still confused.
>>>
>>> What do you mean by "pipe"? should it be "socket" instead?
>>
>> Sorry, yes, I used "pipe" and "socket" interchangeably there.
>>
>>> What is not designed? cleanup being done, my tests passing or the
>>> synchronization?
>>
>> The synchronization. If the daemon were implemented as:
>>
>>   if (!strcmp(action.buf, "exit")) {
>>         /* acknowledge that we got command */
>>         fclose(out);
>>         exit(0);
>>   }
>>
>> for example, then the client would exit at the same that the daemon is
>> cleaning up the socket, and we may or may not call test_path_is_missing
>> before the cleanup is done.
>>
>> I think it's OK to rely on that, but we may want to put a comment to
>> that effect in the daemon code so that it doesn't get changed.
>
> The current implementation is natural for me. But having additional comment
> is better.

I believe git-credential--daemon is a better place to comment on, but I'm not sure whether the comment should be included in this patch set. Above all, they are not quite related.

>
>>
>> -Peff
Jeff King· Mar 18, 2016, 06:12 UTC · re: 惠轶群 · lore

[PATCH] credential-cache--daemon: clarify "exit" action semantics

On Fri, Mar 18, 2016 at 02:02:08PM +0800, 惠轶群 wrote:
> I believe git-credential--daemon is a better place to comment on, but
> I'm not sure whether the comment should be included in this patch set.
> Above all, they are not quite related.
Yes, it could be completely separate from your series.
Here is what I think we should do:
-- >8 --
Subject: credential-cache--daemon: clarify "exit" action semantics

When this code was originally written, there wasn't much thought given to the timing between a client asking for "exit", the daemon signaling that the action is done (with EOF), and the actual cleanup of the socket.

However, we need to care about this so that our test scripts do not end up racy (e.g., by asking for an exit and checking that the socket was cleaned up). The code that is already there happens to behave very reasonably; let's add a comment to make it clear that any changes should retain the same behavior.

Signed-off-by: Jeff King <peff@peff.net>
---
 credential-cache--daemon.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/credential-cache--daemon.c b/credential-cache--daemon.c
index caef21e..291c0fd 100644
--- a/credential-cache--daemon.c
+++ b/credential-cache--daemon.c
@@ -126,8 +126,17 @@ static void serve_one_client(FILE *in, FILE *out)
 			fprintf(out, "password=%s\n", e->item.password);
 		}
 	}
-	else if (!strcmp(action.buf, "exit"))
+	else if (!strcmp(action.buf, "exit")) {
+		/*
+		 * It's important that we clean up our socket first, and then
+		 * signal the client only once we have finished the cleanup.
+		 * Calling exit() directly does this, because we clean up in
+		 * our atexit() handler, and then signal the client when our
+		 * process actually ends, which closes the socket and gives
+		 * them EOF.
+		 */
 		exit(0);
+	}
 	else if (!strcmp(action.buf, "erase"))
 		remove_credential(&c);
 	else if (!strcmp(action.buf, "store")) {
-- 
2.8.0.rc3.378.gf2f7872

← back to recent threads