aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/git-credential.txt28
-rw-r--r--builtin/credential-cache.c10
-rw-r--r--builtin/credential.c6
-rw-r--r--credential.c11
-rw-r--r--credential.h6
5 files changed, 60 insertions, 1 deletions
diff --git a/Documentation/git-credential.txt b/Documentation/git-credential.txt
index 3d3accc273..e41493292f 100644
--- a/Documentation/git-credential.txt
+++ b/Documentation/git-credential.txt
@@ -8,7 +8,7 @@ git-credential - Retrieve and store user credentials
SYNOPSIS
--------
------------------
-'git credential' (fill|approve|reject)
+'git credential' (fill|approve|reject|capability)
------------------
DESCRIPTION
@@ -41,6 +41,9 @@ If the action is `reject`, git-credential will send the description to
any configured credential helpers, which may erase any stored
credentials matching the description.
+If the action is `capability`, git-credential will announce any capabilities
+it supports to standard output.
+
If the action is `approve` or `reject`, no output should be emitted.
TYPICAL USE OF GIT CREDENTIAL
@@ -263,6 +266,29 @@ is supported, but they should not be provided without the capability.
Unrecognised attributes and capabilities are silently discarded.
+[[CAPA-IOFMT]]
+CAPABILITY INPUT/OUTPUT FORMAT
+------------------------------
+
+For `git credential capability`, the format is slightly different. First, a
+`version 0` announcement is made to indicate the current version of the
+protocol, and then each capability is announced with a line like `capability
+authtype`. Credential helpers may also implement this format, again with the
+`capability` argument. Additional lines may be added in the future; callers
+should ignore lines which they don't understand.
+
+Because this is a new part of the credential helper protocol, older versions of
+Git, as well as some credential helpers, may not support it. If a non-zero
+exit status is received, or if the first line doesn't start with the word
+`version` and a space, callers should assume that no capabilities are supported.
+
+The intention of this format is to differentiate it from the credential output
+in an unambiguous way. It is possible to use very simple credential helpers
+(e.g., inline shell scripts) which always produce identical output. Using a
+distinct format allows users to continue to use this syntax without having to
+worry about correctly implementing capability advertisements or accidentally
+confusing callers querying for capabilities.
+
GIT
---
Part of the linkgit:git[1] suite
diff --git a/builtin/credential-cache.c b/builtin/credential-cache.c
index bba96d4ffd..f5c989e2b2 100644
--- a/builtin/credential-cache.c
+++ b/builtin/credential-cache.c
@@ -1,4 +1,5 @@
#include "builtin.h"
+#include "credential.h"
#include "gettext.h"
#include "parse-options.h"
#include "path.h"
@@ -127,6 +128,13 @@ static char *get_socket_path(void)
return socket;
}
+static void announce_capabilities(void)
+{
+ struct credential c = CREDENTIAL_INIT;
+ c.capa_authtype.request_initial = 1;
+ credential_announce_capabilities(&c, stdout);
+}
+
int cmd_credential_cache(int argc, const char **argv, const char *prefix)
{
char *socket_path = NULL;
@@ -160,6 +168,8 @@ int cmd_credential_cache(int argc, const char **argv, const char *prefix)
do_cache(socket_path, op, timeout, FLAG_RELAY);
else if (!strcmp(op, "store"))
do_cache(socket_path, op, timeout, FLAG_RELAY|FLAG_SPAWN);
+ else if (!strcmp(op, "capability"))
+ announce_capabilities();
else
; /* ignore unknown operation */
diff --git a/builtin/credential.c b/builtin/credential.c
index 3568e57025..5100d441f2 100644
--- a/builtin/credential.c
+++ b/builtin/credential.c
@@ -17,6 +17,12 @@ int cmd_credential(int argc, const char **argv, const char *prefix UNUSED)
usage(usage_msg);
op = argv[1];
+ if (!strcmp(op, "capability")) {
+ credential_set_all_capabilities(&c, CREDENTIAL_OP_INITIAL);
+ credential_announce_capabilities(&c, stdout);
+ return 0;
+ }
+
if (credential_read(&c, stdin, CREDENTIAL_OP_INITIAL) < 0)
die("unable to read credential from stdin");
diff --git a/credential.c b/credential.c
index ffaf31499e..758528b291 100644
--- a/credential.c
+++ b/credential.c
@@ -72,6 +72,17 @@ void credential_set_all_capabilities(struct credential *c,
credential_set_capability(&c->capa_state, op_type);
}
+static void announce_one(struct credential_capability *cc, const char *name, FILE *fp) {
+ if (cc->request_initial)
+ fprintf(fp, "capability %s\n", name);
+}
+
+void credential_announce_capabilities(struct credential *c, FILE *fp) {
+ fprintf(fp, "version 0\n");
+ announce_one(&c->capa_authtype, "authtype", fp);
+ announce_one(&c->capa_state, "state", fp);
+}
+
int credential_match(const struct credential *want,
const struct credential *have, int match_password)
{
diff --git a/credential.h b/credential.h
index f8df10937c..af8c287ff2 100644
--- a/credential.h
+++ b/credential.h
@@ -254,6 +254,12 @@ void credential_set_all_capabilities(struct credential *c,
void credential_clear_secrets(struct credential *c);
/**
+ * Print a list of supported capabilities and version numbers to standard
+ * output.
+ */
+void credential_announce_capabilities(struct credential *c, FILE *fp);
+
+/**
* Prepares the credential for the next iteration of the helper protocol by
* updating the state headers to send with the ones read by the last iteration
* of the protocol.