git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH/RFC] credentials helpers+remote helpers
@ 2012-06-07 14:35 Javier.Roucher-Iglesias
  2012-06-07 17:13 ` Matthieu Moy
  2012-06-07 19:22 ` Junio C Hamano
  0 siblings, 2 replies; 3+ messages in thread
From: Javier.Roucher-Iglesias @ 2012-06-07 14:35 UTC (permalink / raw)
  To: git
  Cc: Javier Roucher, Pavel Volek, NGUYEN Kim Thuat,
	ROUCHER IGLESIAS Javier, Matthieu Moy

From: Javier Roucher <jroucher@gmail.com>


Add "git credential" plumbing command

The credential API is in C, and not available to scripting languages.
Expose the functionalities of the API by wrapping them into a new
plumbing command "git credentials".

Signed-off-by: Pavel Volek <Pavel.Volek@ensimag.imag.fr>
Signed-off-by: NGUYEN Kim Thuat <Kim-Thuat.Nguyen@ensimag.imag.fr>
Signed-off-by: ROUCHER IGLESIAS Javier <roucherj@ensimag.imag.fr>
Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>
---
 .gitignore                       |  1 +
 Documentation/git-credential.txt | 70 ++++++++++++++++++++++++++++++++++++++++
 Makefile                         |  1 +
 builtin.h                        |  1 +
 builtin/credential.c             | 40 +++++++++++++++++++++++
 git.c                            |  1 +
 6 files changed, 114 insertions(+)
 create mode 100644 Documentation/git-credential.txt
 create mode 100644 builtin/credential.c

diff --git a/.gitignore b/.gitignore
index bf66648..7d1d86e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,6 +31,7 @@
 /git-commit-tree
 /git-config
 /git-count-objects
+/git-credential
 /git-credential-cache
 /git-credential-cache--daemon
 /git-credential-store
diff --git a/Documentation/git-credential.txt b/Documentation/git-credential.txt
new file mode 100644
index 0000000..a6e1d0a
--- /dev/null
+++ b/Documentation/git-credential.txt
@@ -0,0 +1,70 @@
+git-credential(7)
+=================
+
+NAME
+----
+git-credential - Providing and storing user credentials to git
+
+SYNOPSIS
+--------
+------------------
+git credential [fill|approve|reject]
+
+------------------
+
+DESCRIPTION
+-----------
+
+Git-credential permits to save username, password, host, path and protocol.
+When you invoke git-credential, you can ask for a password, using the command
+'git credential fill'.
+Providing them by STDIN: 
+
+		username=admin\n 
+		protocol=[http|https]\n
+		host=localhost\n
+		path=/dir\n\n
+
+-If git-credential system, have the password already stored
+git-credential will answer by STDOUT:
+	
+		username=admin\n
+		password=*****\n
+
+-If it is not stored, git-credential will ask you to enter 
+the password:
+		
+		> Password for '[http|https]admin@localhost':
+
+Then if password is correct, you can store using command
+'git crendential approve' providing the structure, by STDIN.
+
+		username=admin\n 
+		password=*****\n
+		protocol=[http|https]\n
+		host=localhost\n
+		path=/dir\n\n
+
+If the password is refused, you can delete using command
+'git credential reject' providing the same structure.
+
+
+REQUESTING CREDENTIALS
+----------------------
+
+1. The 'git credential fill' makes the structure:
+		username=foo
+		password=****
+		protocol=[http|https]
+		localhost=url
+		path=/direction
+
+   with this structure it will be able to save your
+   credentials, and if the credential is allready stored,
+   it will fill the password.
+
+2. Then 'git credential approve' to store them.
+
+3. Otherwise, if the credential is not correct you can do
+  'git credential reject' to delete the credential.
+-------------------------------------------
diff --git a/Makefile b/Makefile
index 4592f1f..3f53da8 100644
--- a/Makefile
+++ b/Makefile
@@ -827,6 +827,7 @@ BUILTIN_OBJS += builtin/commit-tree.o
 BUILTIN_OBJS += builtin/commit.o
 BUILTIN_OBJS += builtin/config.o
 BUILTIN_OBJS += builtin/count-objects.o
+BUILTIN_OBJS += builtin/credential.o
 BUILTIN_OBJS += builtin/describe.o
 BUILTIN_OBJS += builtin/diff-files.o
 BUILTIN_OBJS += builtin/diff-index.o
diff --git a/builtin.h b/builtin.h
index 338f540..48feddc 100644
--- a/builtin.h
+++ b/builtin.h
@@ -66,6 +66,7 @@ extern int cmd_commit(int argc, const char **argv, const char *prefix);
 extern int cmd_commit_tree(int argc, const char **argv, const char *prefix);
 extern int cmd_config(int argc, const char **argv, const char *prefix);
 extern int cmd_count_objects(int argc, const char **argv, const char *prefix);
+extern int cmd_credential(int argc, const char **argv, const char *prefix);
 extern int cmd_describe(int argc, const char **argv, const char *prefix);
 extern int cmd_diff_files(int argc, const char **argv, const char *prefix);
 extern int cmd_diff_index(int argc, const char **argv, const char *prefix);
diff --git a/builtin/credential.c b/builtin/credential.c
new file mode 100644
index 0000000..89f976b
--- /dev/null
+++ b/builtin/credential.c
@@ -0,0 +1,40 @@
+#include <stdio.h>
+#include "cache.h"
+#include "credential.h"
+#include "string-list.h"
+
+static const char usage_msg[] =
+"credential <fill|approve|reject> [helper...]";
+
+void cmd_credential (int argc, char **argv, const char *prefix){
+	const char *op;
+	struct credential c = CREDENTIAL_INIT;
+	int i;
+
+	op = argv[1];
+	if (!op)
+		usage(usage_msg);
+
+	for (i = 2; i < argc; i++)
+		string_list_append(&c.helpers, argv[i]);
+
+	if (credential_read(&c, stdin) < 0)
+		die("unable to read credential from stdin");
+
+	if (!strcmp(op, "fill")) {
+		credential_fill(&c);
+		if (c.username)
+			printf("username=%s\n", c.username);
+		if (c.password)
+			printf("password=%s\n", c.password);
+	}
+	else if (!strcmp(op, "approve")) {
+		credential_approve(&c);
+	}
+	else if (!strcmp(op, "reject")) {
+		credential_reject(&c);
+	}
+	else
+		usage(usage_msg);
+}
+
diff --git a/git.c b/git.c
index d232de9..211f01f 100644
--- a/git.c
+++ b/git.c
@@ -353,6 +353,7 @@ static void handle_internal_command(int argc, const char **argv)
 		{ "commit-tree", cmd_commit_tree, RUN_SETUP },
 		{ "config", cmd_config, RUN_SETUP_GENTLY },
 		{ "count-objects", cmd_count_objects, RUN_SETUP },
+		{ "credential", cmd_credential, RUN_SETUP },
 		{ "describe", cmd_describe, RUN_SETUP },
 		{ "diff", cmd_diff },
 		{ "diff-files", cmd_diff_files, RUN_SETUP | NEED_WORK_TREE },
-- 
1.7.11.rc0.5.ge0c9cc0.dirty

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH/RFC] credentials helpers+remote helpers
  2012-06-07 14:35 [PATCH/RFC] credentials helpers+remote helpers Javier.Roucher-Iglesias
@ 2012-06-07 17:13 ` Matthieu Moy
  2012-06-07 19:22 ` Junio C Hamano
  1 sibling, 0 replies; 3+ messages in thread
From: Matthieu Moy @ 2012-06-07 17:13 UTC (permalink / raw)
  To: Javier.Roucher-Iglesias
  Cc: git, Javier Roucher, Pavel Volek, NGUYEN Kim Thuat,
	ROUCHER IGLESIAS Javier

> Subject: Re: [PATCH/RFC] credentials helpers+remote helpers

This is not a good title. The one you have below (which I suggested
off-list) should be the first line of the patch.

Javier.Roucher-Iglesias@ensimag.imag.fr writes:

> Add "git credential" plumbing command

(I mean this one)

>  .gitignore                       |  1 +
>  Documentation/git-credential.txt | 70 ++++++++++++++++++++++++++++++++++++++++
>  Makefile                         |  1 +
>  builtin.h                        |  1 +
>  builtin/credential.c             | 40 +++++++++++++++++++++++
>  git.c                            |  1 +

No tests?

Since this new command is essentially a copy-paste of test-credential.c,
it would indeed make sense to replace test-credential calls in the
scripts by calls to this "git credential" command.

> index 0000000..a6e1d0a
> --- /dev/null
> +++ b/Documentation/git-credential.txt

This file is not valid asciidoc. Please, run "make doc" and see if the
generated HTML is right. Currently, it says

    SUBDIR ../
make[1]: `GIT-VERSION-FILE' is up to date.
    ASCIIDOC git-credential.html
asciidoc: ERROR: git-credential.txt: line 69: [blockdef-listing] missing closing delimiter
make: *** [git-credential.html] Error 1

(didn't I already mention it off-list?)
> +------------------
> +git credential [fill|approve|reject]
> +
> +------------------
[...]
> +static const char usage_msg[] =
> +"credential <fill|approve|reject> [helper...]";

Which one is right?

I already suggested several times that you get rid of this "helper"
argument (inherited from test-credential), or that you give it a better
API (e.g. --helper HELPER, but not positional argument). If this
argument is usefull, then keep it but it should be documented properly.

> +Git-credential permits to save username, password, host, path and protocol.
> +When you invoke git-credential, you can ask for a password, using the command
> +'git credential fill'.

Who is "you" here? This "you" is the developer writing a script using
"git credential", while this one :

> +-If it is not stored, git-credential will ask you to enter 
> +the password:
> +		
> +		> Password for '[http|https]admin@localhost':

... is the user of the script. Please be more precise, e.g. "a script
can ask ...", "the user will be prompted for a password".

> +Then if password is correct, you can store using command

if _the_ password ... you can store _it_ using ...

> +If the password is refused, you can delete using command

delete _it_

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH/RFC] credentials helpers+remote helpers
  2012-06-07 14:35 [PATCH/RFC] credentials helpers+remote helpers Javier.Roucher-Iglesias
  2012-06-07 17:13 ` Matthieu Moy
@ 2012-06-07 19:22 ` Junio C Hamano
  1 sibling, 0 replies; 3+ messages in thread
From: Junio C Hamano @ 2012-06-07 19:22 UTC (permalink / raw)
  To: Javier.Roucher-Iglesias
  Cc: git, Javier Roucher, Pavel Volek, NGUYEN Kim Thuat,
	ROUCHER IGLESIAS Javier, Matthieu Moy

Javier.Roucher-Iglesias@ensimag.imag.fr writes:

> From: Javier Roucher <jroucher@gmail.com>
>
>
> Add "git credential" plumbing command
>
> The credential API is in C, and not available to scripting languages.
> Expose the functionalities of the API by wrapping them into a new
> plumbing command "git credentials".
>
> Signed-off-by: Pavel Volek <Pavel.Volek@ensimag.imag.fr>
> Signed-off-by: NGUYEN Kim Thuat <Kim-Thuat.Nguyen@ensimag.imag.fr>
> Signed-off-by: ROUCHER IGLESIAS Javier <roucherj@ensimag.imag.fr>
> Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>

In addition to all good comments already given by Matthieu,...

> diff --git a/Documentation/git-credential.txt b/Documentation/git-credential.txt
> new file mode 100644
> index 0000000..a6e1d0a
> --- /dev/null
> +++ b/Documentation/git-credential.txt
> @@ -0,0 +1,70 @@
> +git-credential(7)
> +=================
> +
> +NAME
> +----
> +git-credential - Providing and storing user credentials to git

This sounds as if we are storing passwords "in git", which is not
exactly the point of the credential API, no?

> +SYNOPSIS
> +--------
> +------------------
> +git credential [fill|approve|reject]
> +
> +------------------
> +
> +DESCRIPTION
> +-----------
> +
> +Git-credential permits to save username, password, host, path and protocol.
> +When you invoke git-credential, you can ask for a password, using the command
> +'git credential fill'.
> +Providing them by STDIN: 
> +
> +		username=admin\n 
> +		protocol=[http|https]\n
> +		host=localhost\n
> +		path=/dir\n\n

It's a bit strange way to convey that the user feeds record
separated by a blank line, and each column in a record is terminated
with a newline.

How about saying that more explicitly?  E.g. "when taking data from
the standard input, the program treats each line as a separate data
item, and the end of series of data item is signalled by a blank
line" or something?

> +-If git-credential system, have the password already stored
> +git-credential will answer by STDOUT:
> +	
> +		username=admin\n
> +		password=*****\n

Does the reading side get any clue that there is no more output,
like you gave yourself on the input side (i.e. it can and should
read until it sees a blank line)?

Shouldn't it?

> +-If it is not stored, git-credential will ask you to enter 
> +the password:
> +		
> +		> Password for '[http|https]admin@localhost':
> +
> +Then if password is correct, you can store using command
> +'git crendential approve' providing the structure, by STDIN.
> +
> +		username=admin\n 
> +		password=*****\n
> +		protocol=[http|https]\n
> +		host=localhost\n
> +		path=/dir\n\n
> +
> +If the password is refused, you can delete using command
> +'git credential reject' providing the same structure.

It is unclear who decides "correct" vs "refused" here.

Perhaps it would help to describe the purpose of the script that
uses this command first.  My understanding is that there are three
actors: the end user, the script that uses "git credential" and an
external system that wants to authenticate the user.

    _
   / \        +------------------+      +-----------------+
  | U |       |                  |      |                 |
   \ /        | Script that uses |      | External system |
  --+--  <==> | "git credential" | <==> |                 | 
    ^         +------------------+      +-----------------+
   / \                 ^
                       |
                       v
                credential API

And the "Script" is trying to respond to the external system with
credential material on behalf of the user.  For that, if the script
knows the username, it can give the <user,proto,host,path> tuple to
"git credential", and if "git credential" knows the password, it
will be given to the script. If it does not, it may ask the user and
obtain it before giving it back to the script.

Is that what is going on?

Assuming it is, after that happens, the script gives the credential
information to the external system. The external system may or may
not accept that credential, and that is what decides "correct" vs
"refused".

After that, the script tells the "git credential" the result; giving
"reject" to it to purge the credential information that it already
knows the external system will reject, for example.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-06-07 19:22 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-07 14:35 [PATCH/RFC] credentials helpers+remote helpers Javier.Roucher-Iglesias
2012-06-07 17:13 ` Matthieu Moy
2012-06-07 19:22 ` Junio C Hamano

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).