credential: move doc to credential.h
Move the documentation from Documentation/technical/api-credentials.txt to credential.h as it's easier for the developers to find the usage information beside the code instead of looking for it in another doc file. Documentation/technical/api-credentials.txt is removed because the information it has is now redundant and it'll be hard to keep it up to date and synchronized with the documentation in the header file. Documentation/git-credential.txt and Documentation/gitcredentials.txt now link to credential.h instead of Documentation/technical/api-credentials.txt for details about the credetials API. Signed-off-by: Heba Waly <heba.waly@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Heba Waly committed
Nov 17, 2019 at 21:04 UTC
f3b9055624cb797b1956f100a40104c9aceb4835
4 files changed
+238
-275
Documentation/git-credential.txt
+1
-2
@@ -19,8 +19,7 @@ from system-specific helpers, as well as prompting the user for
19
usernames and passwords. The git-credential command exposes this
20
interface to scripts which may want to retrieve, store, or prompt for
21
credentials in the same manner as Git. The design of this scriptable
22
-interface models the internal C API; see
23
-link:technical/api-credentials.html[the Git credential API] for more
22
+interface models the internal C API; see credential.h for more
23
background on the concepts.
24
25
git-credential takes an "action" option on the command-line (one of
Documentation/gitcredentials.txt
+1
-2
@@ -186,8 +186,7 @@ CUSTOM HELPERS
186
--------------
187
188
You can write your own custom helpers to interface with any system in
189
-which you keep credentials. See the documentation for Git's
190
-link:technical/api-credentials.html[credentials API] for details.
189
+which you keep credentials. See credential.h for details.
190
191
GIT
192
---
Documentation/technical/api-credentials.txt
deleted
-271
@@ -1,271 +0,0 @@
1
-credentials API
2
-===============
3
-
4
-The credentials API provides an abstracted way of gathering username and
5
-password credentials from the user (even though credentials in the wider
6
-world can take many forms, in this document the word "credential" always
7
-refers to a username and password pair).
8
-
9
-This document describes two interfaces: the C API that the credential
10
-subsystem provides to the rest of Git, and the protocol that Git uses to
11
-communicate with system-specific "credential helpers". If you are
12
-writing Git code that wants to look up or prompt for credentials, see
13
-the section "C API" below. If you want to write your own helper, see
14
-the section on "Credential Helpers" below.
15
-
16
-Typical setup
17
--------------
18
-
19
-------------
20
-+-----------------------+
21
-| Git code (C) |--- to server requiring --->
22
-| | authentication
23
-|.......................|
24
-| C credential API |--- prompt ---> User
25
-+-----------------------+
26
- ^ |
27
- | pipe |
28
- | v
29
-+-----------------------+
30
-| Git credential helper |
31
-+-----------------------+
32
-------------
33
-
34
-The Git code (typically a remote-helper) will call the C API to obtain
35
-credential data like a login/password pair (credential_fill). The
36
-API will itself call a remote helper (e.g. "git credential-cache" or
37
-"git credential-store") that may retrieve credential data from a
38
-store. If the credential helper cannot find the information, the C API
39
-will prompt the user. Then, the caller of the API takes care of
40
-contacting the server, and does the actual authentication.
41
-
42
-C API
43
------
44
-
45
-The credential C API is meant to be called by Git code which needs to
46
-acquire or store a credential. It is centered around an object
47
-representing a single credential and provides three basic operations:
48
-fill (acquire credentials by calling helpers and/or prompting the user),
49
-approve (mark a credential as successfully used so that it can be stored
50
-for later use), and reject (mark a credential as unsuccessful so that it
51
-can be erased from any persistent storage).
52
-
53
-Data Structures
54
-~~~~~~~~~~~~~~~
55
-
56
-`struct credential`::
57
-
58
- This struct represents a single username/password combination
59
- along with any associated context. All string fields should be
60
- heap-allocated (or NULL if they are not known or not applicable).
61
- The meaning of the individual context fields is the same as
62
- their counterparts in the helper protocol; see the section below
63
- for a description of each field.
64
-+
65
-The `helpers` member of the struct is a `string_list` of helpers. Each
66
-string specifies an external helper which will be run, in order, to
67
-either acquire or store credentials. See the section on credential
68
-helpers below. This list is filled-in by the API functions
69
-according to the corresponding configuration variables before
70
-consulting helpers, so there usually is no need for a caller to
71
-modify the helpers field at all.
72
-+
73
-This struct should always be initialized with `CREDENTIAL_INIT` or
74
-`credential_init`.
75
-
76
-
77
-Functions
78
-~~~~~~~~~
79
-
80
-`credential_init`::
81
-
82
- Initialize a credential structure, setting all fields to empty.
83
-
84
-`credential_clear`::
85
-
86
- Free any resources associated with the credential structure,
87
- returning it to a pristine initialized state.
88
-
89
-`credential_fill`::
90
-
91
- Instruct the credential subsystem to fill the username and
92
- password fields of the passed credential struct by first
93
- consulting helpers, then asking the user. After this function
94
- returns, the username and password fields of the credential are
95
- guaranteed to be non-NULL. If an error occurs, the function will
96
- die().
97
-
98
-`credential_reject`::
99
-
100
- Inform the credential subsystem that the provided credentials
101
- have been rejected. This will cause the credential subsystem to
102
- notify any helpers of the rejection (which allows them, for
103
- example, to purge the invalid credentials from storage). It
104
- will also free() the username and password fields of the
105
- credential and set them to NULL (readying the credential for
106
- another call to `credential_fill`). Any errors from helpers are
107
- ignored.
108
-
109
-`credential_approve`::
110
-
111
- Inform the credential subsystem that the provided credentials
112
- were successfully used for authentication. This will cause the
113
- credential subsystem to notify any helpers of the approval, so
114
- that they may store the result to be used again. Any errors
115
- from helpers are ignored.
116
-
117
-`credential_from_url`::
118
-
119
- Parse a URL into broken-down credential fields.
120
-
121
-Example
122
-~~~~~~~
123
-
124
-The example below shows how the functions of the credential API could be
125
-used to login to a fictitious "foo" service on a remote host:
126
-
127
------------------------------------------------------------------------
128
-int foo_login(struct foo_connection *f)
129
-{
130
- int status;
131
- /*
132
- * Create a credential with some context; we don't yet know the
133
- * username or password.
134
- */
135
-
136
- struct credential c = CREDENTIAL_INIT;
137
- c.protocol = xstrdup("foo");
138
- c.host = xstrdup(f->hostname);
139
-
140
- /*
141
- * Fill in the username and password fields by contacting
142
- * helpers and/or asking the user. The function will die if it
143
- * fails.
144
- */
145
- credential_fill(&c);
146
-
147
- /*
148
- * Otherwise, we have a username and password. Try to use it.
149
- */
150
- status = send_foo_login(f, c.username, c.password);
151
- switch (status) {
152
- case FOO_OK:
153
- /* It worked. Store the credential for later use. */
154
- credential_accept(&c);
155
- break;
156
- case FOO_BAD_LOGIN:
157
- /* Erase the credential from storage so we don't try it
158
- * again. */
159
- credential_reject(&c);
160
- break;
161
- default:
162
- /*
163
- * Some other error occurred. We don't know if the
164
- * credential is good or bad, so report nothing to the
165
- * credential subsystem.
166
- */
167
- }
168
-
169
- /* Free any associated resources. */
170
- credential_clear(&c);
171
-
172
- return status;
173
-}
174
------------------------------------------------------------------------
175
-
176
-
177
-Credential Helpers
178
-------------------
179
-
180
-Credential helpers are programs executed by Git to fetch or save
181
-credentials from and to long-term storage (where "long-term" is simply
182
-longer than a single Git process; e.g., credentials may be stored
183
-in-memory for a few minutes, or indefinitely on disk).
184
-
185
-Each helper is specified by a single string in the configuration
186
-variable `credential.helper` (and others, see linkgit:git-config[1]).
187
-The string is transformed by Git into a command to be executed using
188
-these rules:
189
-
190
- 1. If the helper string begins with "!", it is considered a shell
191
- snippet, and everything after the "!" becomes the command.
192
-
193
- 2. Otherwise, if the helper string begins with an absolute path, the
194
- verbatim helper string becomes the command.
195
-
196
- 3. Otherwise, the string "git credential-" is prepended to the helper
197
- string, and the result becomes the command.
198
-
199
-The resulting command then has an "operation" argument appended to it
200
-(see below for details), and the result is executed by the shell.
201
-
202
-Here are some example specifications:
203
-
204
-----------------------------------------------------
205
-# run "git credential-foo"
206
-foo
207
-
208
-# same as above, but pass an argument to the helper
209
-foo --bar=baz
210
-
211
-# the arguments are parsed by the shell, so use shell
212
-# quoting if necessary
213
-foo --bar="whitespace arg"
214
-
215
-# you can also use an absolute path, which will not use the git wrapper
216
-/path/to/my/helper --with-arguments
217
-
218
-# or you can specify your own shell snippet
219
-!f() { echo "password=`cat $HOME/.secret`"; }; f
220
-----------------------------------------------------
221
-
222
-Generally speaking, rule (3) above is the simplest for users to specify.
223
-Authors of credential helpers should make an effort to assist their
224
-users by naming their program "git-credential-$NAME", and putting it in
225
-the $PATH or $GIT_EXEC_PATH during installation, which will allow a user
226
-to enable it with `git config credential.helper $NAME`.
227
-
228
-When a helper is executed, it will have one "operation" argument
229
-appended to its command line, which is one of:
230
-
231
-`get`::
232
-
233
- Return a matching credential, if any exists.
234
-
235
-`store`::
236
-
237
- Store the credential, if applicable to the helper.
238
-
239
-`erase`::
240
-
241
- Remove a matching credential, if any, from the helper's storage.
242
-
243
-The details of the credential will be provided on the helper's stdin
244
-stream. The exact format is the same as the input/output format of the
245
-`git credential` plumbing command (see the section `INPUT/OUTPUT
246
-FORMAT` in linkgit:git-credential[1] for a detailed specification).
247
-
248
-For a `get` operation, the helper should produce a list of attributes
249
-on stdout in the same format. A helper is free to produce a subset, or
250
-even no values at all if it has nothing useful to provide. Any provided
251
-attributes will overwrite those already known about by Git. If a helper
252
-outputs a `quit` attribute with a value of `true` or `1`, no further
253
-helpers will be consulted, nor will the user be prompted (if no
254
-credential has been provided, the operation will then fail).
255
-
256
-For a `store` or `erase` operation, the helper's output is ignored.
257
-If it fails to perform the requested operation, it may complain to
258
-stderr to inform the user. If it does not support the requested
259
-operation (e.g., a read-only store), it should silently ignore the
260
-request.
261
-
262
-If a helper receives any other operation, it should silently ignore the
263
-request. This leaves room for future operations to be added (older
264
-helpers will just ignore the new requests).
265
-
266
-See also
267
---------
268
-
269
-linkgit:gitcredentials[7]
270
-
271
-linkgit:git-config[1] (See configuration variables `credential.*`)
credential.h
+236
@@ -3,8 +3,208 @@
3
4
#include "string-list.h"
5
6
+/**
7
+ * The credentials API provides an abstracted way of gathering username and
8
+ * password credentials from the user.
9
+ *
10
+ * Typical setup
11
+ * -------------
12
+ *
13
+ * ------------
14
+ * +-----------------------+
15
+ * | Git code (C) |--- to server requiring --->
16
+ * | | authentication
17
+ * |.......................|
18
+ * | C credential API |--- prompt ---> User
19
+ * +-----------------------+
20
+ * ^ |
21
+ * | pipe |
22
+ * | v
23
+ * +-----------------------+
24
+ * | Git credential helper |
25
+ * +-----------------------+
26
+ * ------------
27
+ *
28
+ * The Git code (typically a remote-helper) will call the C API to obtain
29
+ * credential data like a login/password pair (credential_fill). The
30
+ * API will itself call a remote helper (e.g. "git credential-cache" or
31
+ * "git credential-store") that may retrieve credential data from a
32
+ * store. If the credential helper cannot find the information, the C API
33
+ * will prompt the user. Then, the caller of the API takes care of
34
+ * contacting the server, and does the actual authentication.
35
+ *
36
+ * C API
37
+ * -----
38
+ *
39
+ * The credential C API is meant to be called by Git code which needs to
40
+ * acquire or store a credential. It is centered around an object
41
+ * representing a single credential and provides three basic operations:
42
+ * fill (acquire credentials by calling helpers and/or prompting the user),
43
+ * approve (mark a credential as successfully used so that it can be stored
44
+ * for later use), and reject (mark a credential as unsuccessful so that it
45
+ * can be erased from any persistent storage).
46
+ *
47
+ * Example
48
+ * ~~~~~~~
49
+ *
50
+ * The example below shows how the functions of the credential API could be
51
+ * used to login to a fictitious "foo" service on a remote host:
52
+ *
53
+ * -----------------------------------------------------------------------
54
+ * int foo_login(struct foo_connection *f)
55
+ * {
56
+ * int status;
57
+ * // Create a credential with some context; we don't yet know the
58
+ * // username or password.
59
+ *
60
+ * struct credential c = CREDENTIAL_INIT;
61
+ * c.protocol = xstrdup("foo");
62
+ * c.host = xstrdup(f->hostname);
63
+ *
64
+ * // Fill in the username and password fields by contacting
65
+ * // helpers and/or asking the user. The function will die if it
66
+ * // fails.
67
+ * credential_fill(&c);
68
+ *
69
+ * // Otherwise, we have a username and password. Try to use it.
70
+ *
71
+ * status = send_foo_login(f, c.username, c.password);
72
+ * switch (status) {
73
+ * case FOO_OK:
74
+ * // It worked. Store the credential for later use.
75
+ * credential_accept(&c);
76
+ * break;
77
+ * case FOO_BAD_LOGIN:
78
+ * // Erase the credential from storage so we don't try it again.
79
+ * credential_reject(&c);
80
+ * break;
81
+ * default:
82
+ * // Some other error occurred. We don't know if the
83
+ * // credential is good or bad, so report nothing to the
84
+ * // credential subsystem.
85
+ * }
86
+ *
87
+ * // Free any associated resources.
88
+ * credential_clear(&c);
89
+ *
90
+ * return status;
91
+ * }
92
+ * -----------------------------------------------------------------------
93
+ *
94
+ * Credential Helpers
95
+ * ------------------
96
+ *
97
+ * Credential helpers are programs executed by Git to fetch or save
98
+ * credentials from and to long-term storage (where "long-term" is simply
99
+ * longer than a single Git process; e.g., credentials may be stored
100
+ * in-memory for a few minutes, or indefinitely on disk).
101
+ *
102
+ * Each helper is specified by a single string in the configuration
103
+ * variable `credential.helper` (and others, see Documentation/git-config.txt).
104
+ * The string is transformed by Git into a command to be executed using
105
+ * these rules:
106
+ *
107
+ * 1. If the helper string begins with "!", it is considered a shell
108
+ * snippet, and everything after the "!" becomes the command.
109
+ *
110
+ * 2. Otherwise, if the helper string begins with an absolute path, the
111
+ * verbatim helper string becomes the command.
112
+ *
113
+ * 3. Otherwise, the string "git credential-" is prepended to the helper
114
+ * string, and the result becomes the command.
115
+ *
116
+ * The resulting command then has an "operation" argument appended to it
117
+ * (see below for details), and the result is executed by the shell.
118
+ *
119
+ * Here are some example specifications:
120
+ *
121
+ * ----------------------------------------------------
122
+ * # run "git credential-foo"
123
+ * foo
124
+ *
125
+ * # same as above, but pass an argument to the helper
126
+ * foo --bar=baz
127
+ *
128
+ * # the arguments are parsed by the shell, so use shell
129
+ * # quoting if necessary
130
+ * foo --bar="whitespace arg"
131
+ *
132
+ * # you can also use an absolute path, which will not use the git wrapper
133
+ * /path/to/my/helper --with-arguments
134
+ *
135
+ * # or you can specify your own shell snippet
136
+ * !f() { echo "password=`cat $HOME/.secret`"; }; f
137
+ * ----------------------------------------------------
138
+ *
139
+ * Generally speaking, rule (3) above is the simplest for users to specify.
140
+ * Authors of credential helpers should make an effort to assist their
141
+ * users by naming their program "git-credential-$NAME", and putting it in
142
+ * the $PATH or $GIT_EXEC_PATH during installation, which will allow a user
143
+ * to enable it with `git config credential.helper $NAME`.
144
+ *
145
+ * When a helper is executed, it will have one "operation" argument
146
+ * appended to its command line, which is one of:
147
+ *
148
+ * `get`::
149
+ *
150
+ * Return a matching credential, if any exists.
151
+ *
152
+ * `store`::
153
+ *
154
+ * Store the credential, if applicable to the helper.
155
+ *
156
+ * `erase`::
157
+ *
158
+ * Remove a matching credential, if any, from the helper's storage.
159
+ *
160
+ * The details of the credential will be provided on the helper's stdin
161
+ * stream. The exact format is the same as the input/output format of the
162
+ * `git credential` plumbing command (see the section `INPUT/OUTPUT
163
+ * FORMAT` in Documentation/git-credential.txt for a detailed specification).
164
+ *
165
+ * For a `get` operation, the helper should produce a list of attributes
166
+ * on stdout in the same format. A helper is free to produce a subset, or
167
+ * even no values at all if it has nothing useful to provide. Any provided
168
+ * attributes will overwrite those already known about by Git. If a helper
169
+ * outputs a `quit` attribute with a value of `true` or `1`, no further
170
+ * helpers will be consulted, nor will the user be prompted (if no
171
+ * credential has been provided, the operation will then fail).
172
+ *
173
+ * For a `store` or `erase` operation, the helper's output is ignored.
174
+ * If it fails to perform the requested operation, it may complain to
175
+ * stderr to inform the user. If it does not support the requested
176
+ * operation (e.g., a read-only store), it should silently ignore the
177
+ * request.
178
+ *
179
+ * If a helper receives any other operation, it should silently ignore the
180
+ * request. This leaves room for future operations to be added (older
181
+ * helpers will just ignore the new requests).
182
+ *
183
+ */
184
+
185
+
186
+/**
187
+ * This struct represents a single username/password combination
188
+ * along with any associated context. All string fields should be
189
+ * heap-allocated (or NULL if they are not known or not applicable).
190
+ * The meaning of the individual context fields is the same as
191
+ * their counterparts in the helper protocol.
192
+ *
193
+ * This struct should always be initialized with `CREDENTIAL_INIT` or
194
+ * `credential_init`.
195
+ */
196
struct credential {
197
+
198
+ /**
199
+ * A `string_list` of helpers. Each string specifies an external
200
+ * helper which will be run, in order, to either acquire or store
201
+ * credentials. This list is filled-in by the API functions
202
+ * according to the corresponding configuration variables before
203
+ * consulting helpers, so there usually is no need for a caller to
204
+ * modify the helpers field at all.
205
+ */
206
struct string_list helpers;
207
+
208
unsigned approved:1,
209
configured:1,
210
quit:1,
@@ -19,16 +219,52 @@ struct credential {
219
220
#define CREDENTIAL_INIT { STRING_LIST_INIT_DUP }
221
222
+/* Initialize a credential structure, setting all fields to empty. */
223
void credential_init(struct credential *);
224
+
225
+/**
226
+ * Free any resources associated with the credential structure, returning
227
+ * it to a pristine initialized state.
228
+ */
229
void credential_clear(struct credential *);
230
231
+/**
232
+ * Instruct the credential subsystem to fill the username and
233
+ * password fields of the passed credential struct by first
234
+ * consulting helpers, then asking the user. After this function
235
+ * returns, the username and password fields of the credential are
236
+ * guaranteed to be non-NULL. If an error occurs, the function will
237
+ * die().
238
+ */
239
void credential_fill(struct credential *);
240
+
241
+/**
242
+ * Inform the credential subsystem that the provided credentials
243
+ * were successfully used for authentication. This will cause the
244
+ * credential subsystem to notify any helpers of the approval, so
245
+ * that they may store the result to be used again. Any errors
246
+ * from helpers are ignored.
247
+ */
248
void credential_approve(struct credential *);
249
+
250
+/**
251
+ * Inform the credential subsystem that the provided credentials
252
+ * have been rejected. This will cause the credential subsystem to
253
+ * notify any helpers of the rejection (which allows them, for
254
+ * example, to purge the invalid credentials from storage). It
255
+ * will also free() the username and password fields of the
256
+ * credential and set them to NULL (readying the credential for
257
+ * another call to `credential_fill`). Any errors from helpers are
258
+ * ignored.
259
+ */
260
void credential_reject(struct credential *);
261
262
int credential_read(struct credential *, FILE *);
263
void credential_write(const struct credential *, FILE *);
264
+
265
+/* Parse a URL into broken-down credential fields. */
266
void credential_from_url(struct credential *, const char *url);
267
+
268
int credential_match(const struct credential *have,
269
const struct credential *want);
270