diff options
author | Junio C Hamano <gitster@pobox.com> | 2011-12-19 16:05:16 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2011-12-19 16:05:16 -0800 |
commit | 367d20ec6b9e8e297537f665fb528346bd0aff27 (patch) | |
tree | bce97747bf55c8b3adffa0a058984aba5ea3225f /Documentation | |
parent | d16520499d2652b5b59dfb25f9cf2d56a4c6913a (diff) | |
parent | 861444f6d702b15713d0875ce9dc5aff64885fba (diff) | |
download | git-367d20ec6b9e8e297537f665fb528346bd0aff27.tar.gz |
Merge branch 'jk/credentials'
* jk/credentials:
t: add test harness for external credential helpers
credentials: add "store" helper
strbuf: add strbuf_add*_urlencode
Makefile: unix sockets may not available on some platforms
credentials: add "cache" helper
docs: end-user documentation for the credential subsystem
credential: make relevance of http path configurable
credential: add credential.*.username
credential: apply helper config
http: use credential API to get passwords
credential: add function for parsing url components
introduce credentials API
t5550: fix typo
test-lib: add test_config_global variant
Conflicts:
strbuf.c
Diffstat (limited to 'Documentation')
-rw-r--r-- | Documentation/Makefile | 1 | ||||
-rw-r--r-- | Documentation/config.txt | 23 | ||||
-rw-r--r-- | Documentation/git-credential-cache--daemon.txt | 26 | ||||
-rw-r--r-- | Documentation/git-credential-cache.txt | 77 | ||||
-rw-r--r-- | Documentation/git-credential-store.txt | 75 | ||||
-rw-r--r-- | Documentation/gitcredentials.txt | 183 | ||||
-rw-r--r-- | Documentation/technical/api-credentials.txt | 245 |
7 files changed, 630 insertions, 0 deletions
diff --git a/Documentation/Makefile b/Documentation/Makefile index 304b31edee..116f17587e 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -7,6 +7,7 @@ MAN5_TXT=gitattributes.txt gitignore.txt gitmodules.txt githooks.txt \ MAN7_TXT=gitcli.txt gittutorial.txt gittutorial-2.txt \ gitcvs-migration.txt gitcore-tutorial.txt gitglossary.txt \ gitdiffcore.txt gitnamespaces.txt gitrevisions.txt gitworkflows.txt +MAN7_TXT += gitcredentials.txt MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT) MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT)) diff --git a/Documentation/config.txt b/Documentation/config.txt index 8a7d2d4cb1..c6630c73e8 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -834,6 +834,29 @@ commit.template:: "{tilde}/" is expanded to the value of `$HOME` and "{tilde}user/" to the specified user's home directory. +credential.helper:: + Specify an external helper to be called when a username or + password credential is needed; the helper may consult external + storage to avoid prompting the user for the credentials. See + linkgit:gitcredentials[7] for details. + +credential.useHttpPath:: + When acquiring credentials, consider the "path" component of an http + or https URL to be important. Defaults to false. See + linkgit:gitcredentials[7] for more information. + +credential.username:: + If no username is set for a network authentication, use this username + by default. See credential.<context>.* below, and + linkgit:gitcredentials[7]. + +credential.<url>.*:: + Any of the credential.* options above can be applied selectively to + some credentials. For example "credential.https://example.com.username" + would set the default username only for https connections to + example.com. See linkgit:gitcredentials[7] for details on how URLs are + matched. + include::diff-config.txt[] difftool.<tool>.path:: diff --git a/Documentation/git-credential-cache--daemon.txt b/Documentation/git-credential-cache--daemon.txt new file mode 100644 index 0000000000..11edc5a173 --- /dev/null +++ b/Documentation/git-credential-cache--daemon.txt @@ -0,0 +1,26 @@ +git-credential-cache--daemon(1) +=============================== + +NAME +---- +git-credential-cache--daemon - temporarily store user credentials in memory + +SYNOPSIS +-------- +[verse] +git credential-cache--daemon <socket> + +DESCRIPTION +----------- + +NOTE: You probably don't want to invoke this command yourself; it is +started automatically when you use linkgit:git-credential-cache[1]. + +This command listens on the Unix domain socket specified by `<socket>` +for `git-credential-cache` clients. Clients may store and retrieve +credentials. Each credential is held for a timeout specified by the +client; once no credentials are held, the daemon exits. + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/git-credential-cache.txt b/Documentation/git-credential-cache.txt new file mode 100644 index 0000000000..f3d09c5d51 --- /dev/null +++ b/Documentation/git-credential-cache.txt @@ -0,0 +1,77 @@ +git-credential-cache(1) +======================= + +NAME +---- +git-credential-cache - helper to temporarily store passwords in memory + +SYNOPSIS +-------- +----------------------------- +git config credential.helper 'cache [options]' +----------------------------- + +DESCRIPTION +----------- + +This command caches credentials in memory for use by future git +programs. The stored credentials never touch the disk, and are forgotten +after a configurable timeout. The cache is accessible over a Unix +domain socket, restricted to the current user by filesystem permissions. + +You probably don't want to invoke this command directly; it is meant to +be used as a credential helper by other parts of git. See +linkgit:gitcredentials[7] or `EXAMPLES` below. + +OPTIONS +------- + +--timeout <seconds>:: + + Number of seconds to cache credentials (default: 900). + +--socket <path>:: + + Use `<path>` to contact a running cache daemon (or start a new + cache daemon if one is not started). Defaults to + `~/.git-credential-cache/socket`. If your home directory is on a + network-mounted filesystem, you may need to change this to a + local filesystem. + +CONTROLLING THE DAEMON +---------------------- + +If you would like the daemon to exit early, forgetting all cached +credentials before their timeout, you can issue an `exit` action: + +-------------------------------------- +git credential-cache exit +-------------------------------------- + +EXAMPLES +-------- + +The point of this helper is to reduce the number of times you must type +your username or password. For example: + +------------------------------------ +$ git config credential.helper cache +$ git push http://example.com/repo.git +Username: <type your username> +Password: <type your password> + +[work for 5 more minutes] +$ git push http://example.com/repo.git +[your credentials are used automatically] +------------------------------------ + +You can provide options via the credential.helper configuration +variable (this example drops the cache time to 5 minutes): + +------------------------------------------------------- +$ git config credential.helper 'cache --timeout=300' +------------------------------------------------------- + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/git-credential-store.txt b/Documentation/git-credential-store.txt new file mode 100644 index 0000000000..31093467d1 --- /dev/null +++ b/Documentation/git-credential-store.txt @@ -0,0 +1,75 @@ +git-credential-store(1) +======================= + +NAME +---- +git-credential-store - helper to store credentials on disk + +SYNOPSIS +-------- +------------------- +git config credential.helper 'store [options]' +------------------- + +DESCRIPTION +----------- + +NOTE: Using this helper will store your passwords unencrypted on disk, +protected only by filesystem permissions. If this is not an acceptable +security tradeoff, try linkgit:git-credential-cache[1], or find a helper +that integrates with secure storage provided by your operating system. + +This command stores credentials indefinitely on disk for use by future +git programs. + +You probably don't want to invoke this command directly; it is meant to +be used as a credential helper by other parts of git. See +linkgit:gitcredentials[7] or `EXAMPLES` below. + +OPTIONS +------- + +--store=<path>:: + + Use `<path>` to store credentials. The file will have its + filesystem permissions set to prevent other users on the system + from reading it, but will not be encrypted or otherwise + protected. Defaults to `~/.git-credentials`. + +EXAMPLES +-------- + +The point of this helper is to reduce the number of times you must type +your username or password. For example: + +------------------------------------------ +$ git config credential.helper store +$ git push http://example.com/repo.git +Username: <type your username> +Password: <type your password> + +[several days later] +$ git push http://example.com/repo.git +[your credentials are used automatically] +------------------------------------------ + +STORAGE FORMAT +-------------- + +The `.git-credentials` file is stored in plaintext. Each credential is +stored on its own line as a URL like: + +------------------------------ +https://user:pass@example.com +------------------------------ + +When git needs authentication for a particular URL context, +credential-store will consider that context a pattern to match against +each entry in the credentials file. If the protocol, hostname, and +username (if we already have one) match, then the password is returned +to git. See the discussion of configuration in linkgit:gitcredentials[7] +for more information. + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/gitcredentials.txt b/Documentation/gitcredentials.txt new file mode 100644 index 0000000000..066f825f2e --- /dev/null +++ b/Documentation/gitcredentials.txt @@ -0,0 +1,183 @@ +gitcredentials(7) +================= + +NAME +---- +gitcredentials - providing usernames and passwords to git + +SYNOPSIS +-------- +------------------ +git config credential.https://example.com.username myusername +git config credential.helper "$helper $options" +------------------ + +DESCRIPTION +----------- + +Git will sometimes need credentials from the user in order to perform +operations; for example, it may need to ask for a username and password +in order to access a remote repository over HTTP. This manual describes +the mechanisms git uses to request these credentials, as well as some +features to avoid inputting these credentials repeatedly. + +REQUESTING CREDENTIALS +---------------------- + +Without any credential helpers defined, git will try the following +strategies to ask the user for usernames and passwords: + +1. If the `GIT_ASKPASS` environment variable is set, the program + specified by the variable is invoked. A suitable prompt is provided + to the program on the command line, and the user's input is read + from its standard output. + +2. Otherwise, if the `core.askpass` configuration variable is set, its + value is used as above. + +3. Otherwise, if the `SSH_ASKPASS` environment variable is set, its + value is used as above. + +4. Otherwise, the user is prompted on the terminal. + +AVOIDING REPETITION +------------------- + +It can be cumbersome to input the same credentials over and over. Git +provides two methods to reduce this annoyance: + +1. Static configuration of usernames for a given authentication context. + +2. Credential helpers to cache or store passwords, or to interact with + a system password wallet or keychain. + +The first is simple and appropriate if you do not have secure storage available +for a password. It is generally configured by adding this to your config: + +--------------------------------------- +[credential "https://example.com"] + username = me +--------------------------------------- + +Credential helpers, on the other hand, are external programs from which git can +request both usernames and passwords; they typically interface with secure +storage provided by the OS or other programs. + +To use a helper, you must first select one to use. Git currently +includes the following helpers: + +cache:: + + Cache credentials in memory for a short period of time. See + linkgit:git-credential-cache[1] for details. + +store:: + + Store credentials indefinitely on disk. See + linkgit:git-credential-store[1] for details. + +You may also have third-party helpers installed; search for +`credential-*` in the output of `git help -a`, and consult the +documentation of individual helpers. Once you have selected a helper, +you can tell git to use it by putting its name into the +credential.helper variable. + +1. Find a helper. ++ +------------------------------------------- +$ git help -a | grep credential- +credential-foo +------------------------------------------- + +2. Read its description. ++ +------------------------------------------- +$ git help credential-foo +------------------------------------------- + +3. Tell git to use it. ++ +------------------------------------------- +$ git config --global credential.helper foo +------------------------------------------- + +If there are multiple instances of the `credential.helper` configuration +variable, each helper will be tried in turn, and may provide a username, +password, or nothing. Once git has acquired both a username and a +password, no more helpers will be tried. + + +CREDENTIAL CONTEXTS +------------------- + +Git considers each credential to have a context defined by a URL. This context +is used to look up context-specific configuration, and is passed to any +helpers, which may use it as an index into secure storage. + +For instance, imagine we are accessing `https://example.com/foo.git`. When git +looks into a config file to see if a section matches this context, it will +consider the two a match if the context is a more-specific subset of the +pattern in the config file. For example, if you have this in your config file: + +-------------------------------------- +[credential "https://example.com"] + username = foo +-------------------------------------- + +then we will match: both protocols are the same, both hosts are the same, and +the "pattern" URL does not care about the path component at all. However, this +context would not match: + +-------------------------------------- +[credential "https://kernel.org"] + username = foo +-------------------------------------- + +because the hostnames differ. Nor would it match `foo.example.com`; git +compares hostnames exactly, without considering whether two hosts are part of +the same domain. Likewise, a config entry for `http://example.com` would not +match: git compares the protocols exactly. + + +CONFIGURATION OPTIONS +--------------------- + +Options for a credential context can be configured either in +`credential.\*` (which applies to all credentials), or +`credential.<url>.\*`, where <url> matches the context as described +above. + +The following options are available in either location: + +helper:: + + The name of an external credential helper, and any associated options. + If the helper name is not an absolute path, then the string `git + credential-` is prepended. The resulting string is executed by the + shell (so, for example, setting this to `foo --option=bar` will execute + `git credential-foo --option=bar` via the shell. See the manual of + specific helpers for examples of their use. + +username:: + + A default username, if one is not provided in the URL. + +useHttpPath:: + + By default, git does not consider the "path" component of an http URL + to be worth matching via external helpers. This means that a credential + stored for `https://example.com/foo.git` will also be used for + `https://example.com/bar.git`. If you do want to distinguish these + cases, set this option to `true`. + + +CUSTOM HELPERS +-------------- + +You can write your own custom helpers to interface with any system in +which you keep credentials. See the documentation for git's +link:technical/api-credentials.html[credentials API] for details. + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/technical/api-credentials.txt b/Documentation/technical/api-credentials.txt new file mode 100644 index 0000000000..21ca6a2553 --- /dev/null +++ b/Documentation/technical/api-credentials.txt @@ -0,0 +1,245 @@ +credentials API +=============== + +The credentials API provides an abstracted way of gathering username and +password credentials from the user (even though credentials in the wider +world can take many forms, in this document the word "credential" always +refers to a username and password pair). + +Data Structures +--------------- + +`struct credential`:: + + This struct represents a single username/password combination + along with any associated context. All string fields should be + heap-allocated (or NULL if they are not known or not applicable). + The meaning of the individual context fields is the same as + their counterparts in the helper protocol; see the section below + for a description of each field. ++ +The `helpers` member of the struct is a `string_list` of helpers. Each +string specifies an external helper which will be run, in order, to +either acquire or store credentials. See the section on credential +helpers below. ++ +This struct should always be initialized with `CREDENTIAL_INIT` or +`credential_init`. + + +Functions +--------- + +`credential_init`:: + + Initialize a credential structure, setting all fields to empty. + +`credential_clear`:: + + Free any resources associated with the credential structure, + returning it to a pristine initialized state. + +`credential_fill`:: + + Instruct the credential subsystem to fill the username and + password fields of the passed credential struct by first + consulting helpers, then asking the user. After this function + returns, the username and password fields of the credential are + guaranteed to be non-NULL. If an error occurs, the function will + die(). + +`credential_reject`:: + + Inform the credential subsystem that the provided credentials + have been rejected. This will cause the credential subsystem to + notify any helpers of the rejection (which allows them, for + example, to purge the invalid credentials from storage). It + will also free() the username and password fields of the + credential and set them to NULL (readying the credential for + another call to `credential_fill`). Any errors from helpers are + ignored. + +`credential_approve`:: + + Inform the credential subsystem that the provided credentials + were successfully used for authentication. This will cause the + credential subsystem to notify any helpers of the approval, so + that they may store the result to be used again. Any errors + from helpers are ignored. + +`credential_from_url`:: + + Parse a URL into broken-down credential fields. + +Example +------- + +The example below shows how the functions of the credential API could be +used to login to a fictitious "foo" service on a remote host: + +----------------------------------------------------------------------- +int foo_login(struct foo_connection *f) +{ + int status; + /* + * Create a credential with some context; we don't yet know the + * username or password. + */ + + struct credential c = CREDENTIAL_INIT; + c.protocol = xstrdup("foo"); + c.host = xstrdup(f->hostname); + + /* + * Fill in the username and password fields by contacting + * helpers and/or asking the user. The function will die if it + * fails. + */ + credential_fill(&c); + + /* + * Otherwise, we have a username and password. Try to use it. + */ + status = send_foo_login(f, c.username, c.password); + switch (status) { + case FOO_OK: + /* It worked. Store the credential for later use. */ + credential_accept(&c); + break; + case FOO_BAD_LOGIN: + /* Erase the credential from storage so we don't try it + * again. */ + credential_reject(&c); + break; + default: + /* + * Some other error occured. We don't know if the + * credential is good or bad, so report nothing to the + * credential subsystem. + */ + } + + /* Free any associated resources. */ + credential_clear(&c); + + return status; +} +----------------------------------------------------------------------- + + +Credential Helpers +------------------ + +Credential helpers are programs executed by git to fetch or save +credentials from and to long-term storage (where "long-term" is simply +longer than a single git process; e.g., credentials may be stored +in-memory for a few minutes, or indefinitely on disk). + +Each helper is specified by a single string. The string is transformed +by git into a command to be executed using these rules: + + 1. If the helper string begins with "!", it is considered a shell + snippet, and everything after the "!" becomes the command. + + 2. Otherwise, if the helper string begins with an absolute path, the + verbatim helper string becomes the command. + + 3. Otherwise, the string "git credential-" is prepended to the helper + string, and the result becomes the command. + +The resulting command then has an "operation" argument appended to it +(see below for details), and the result is executed by the shell. + +Here are some example specifications: + +---------------------------------------------------- +# run "git credential-foo" +foo + +# same as above, but pass an argument to the helper +foo --bar=baz + +# the arguments are parsed by the shell, so use shell +# quoting if necessary +foo --bar="whitespace arg" + +# you can also use an absolute path, which will not use the git wrapper +/path/to/my/helper --with-arguments + +# or you can specify your own shell snippet +!f() { echo "password=`cat $HOME/.secret`"; }; f +---------------------------------------------------- + +Generally speaking, rule (3) above is the simplest for users to specify. +Authors of credential helpers should make an effort to assist their +users by naming their program "git-credential-$NAME", and putting it in +the $PATH or $GIT_EXEC_PATH during installation, which will allow a user +to enable it with `git config credential.helper $NAME`. + +When a helper is executed, it will have one "operation" argument +appended to its command line, which is one of: + +`get`:: + + Return a matching credential, if any exists. + +`store`:: + + Store the credential, if applicable to the helper. + +`erase`:: + + Remove a matching credential, if any, from the helper's storage. + +The details of the credential will be provided on the helper's stdin +stream. The credential is split into a set of named attributes. +Attributes are provided to the helper, one per line. Each attribute is +specified by a key-value pair, separated by an `=` (equals) sign, +followed by a newline. The key may contain any bytes except `=`, +newline, or NUL. The value may contain any bytes except newline or NUL. +In both cases, all bytes are treated as-is (i.e., there is no quoting, +and one cannot transmit a value with newline or NUL in it). The list of +attributes is terminated by a blank line or end-of-file. + +Git will send the following attributes (but may not send all of +them for a given credential; for example, a `host` attribute makes no +sense when dealing with a non-network protocol): + +`protocol`:: + + The protocol over which the credential will be used (e.g., + `https`). + +`host`:: + + The remote hostname for a network credential. + +`path`:: + + The path with which the credential will be used. E.g., for + accessing a remote https repository, this will be the + repository's path on the server. + +`username`:: + + The credential's username, if we already have one (e.g., from a + URL, from the user, or from a previously run helper). + +`password`:: + + The credential's password, if we are asking it to be stored. + +For a `get` operation, the helper should produce a list of attributes +on stdout in the same format. A helper is free to produce a subset, or +even no values at all if it has nothing useful to provide. Any provided +attributes will overwrite those already known about by git. + +For a `store` or `erase` operation, the helper's output is ignored. +If it fails to perform the requested operation, it may complain to +stderr to inform the user. If it does not support the requested +operation (e.g., a read-only store), it should silently ignore the +request. + +If a helper receives any other operation, it should silently ignore the +request. This leaves room for future operations to be added (older +helpers will just ignore the new requests). |