Skip to content

Commit 58faf49

Browse files
committed
Add some docs explaining how we deal with authentication
Explain the sources of the credentials and that we'll happily loop if the user doesn't stop us.
1 parent b75d548 commit 58faf49

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed

docs/guides/authentication/index.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
---
2+
layout: default
3+
---
4+
5+
# Authenticating against a server
6+
7+
One of the big issues you have to deal with when working with with
8+
other people using Git is authenticating to the server you want to
9+
fetch from or push to. In this post we'll explore how libgit2 deals
10+
with presenting the different authentication possibilities across
11+
transport and platforms.
12+
13+
The first place where you can specify the username and password to use
14+
is in the URL. This can be useful in cases where these are always
15+
known, e.g. in specialised scripts which perform some very specific
16+
task. For most uses, however, you do want the ability to specify the
17+
the username and password (or keypair) during the request. An
18+
application might want to even go and ask the human sitting at the
19+
computer for the credentials to the server or it might retrieve the
20+
credentials from its own storage area. To handle this cases, you need
21+
to specify a callback in order for libgit2 to be able to call your
22+
code when it needs to find out about the user's credentials.
23+
24+
The callback is provided via the `credentials` field in the
25+
`git_remote_callbacks` structure. This structure is embedded in both
26+
`git_fetch_options` and `git_push_options` so you can specify it both
27+
both operations.
28+
29+
When libgit2 connects to the server, it may ask for the user's
30+
credentials before performing the operation (this is always the case
31+
for SSH). libgit2 will try to get the information from two places:
32+
33+
1. The URL. If there is a username/password combination in it, it will
34+
try to use that first. For SSH, it will use that username during
35+
the initial query as well.
36+
2. The caller-provided credentials callback. This callback gets the
37+
url and the username from the URL. This can be used to pre-fill a
38+
dialog with the data already in the URL.
39+
40+
If the server doesn't accept the credentials from the callback, it
41+
will be called again. The callback drives the authentication loop. It
42+
will get called until it returns credentials accepted by the server or
43+
it returns an error code.
44+
45+
If the connection is over SSH, libgit2 needs to know which username
46+
will be used before it can know which authentication methods are
47+
available. If one is not provided on the URL, libgit2 will ask the
48+
credentials callback as well, with a supported credential type of
49+
`GIT_CREDTYPE_USERNAME`. libgit2 can then query the server for which
50+
authentication types it supports and will call the credentials
51+
callback again with those types. SSH servers won't allow a username to
52+
be changed within one session, so the username in the URL or provided
53+
in the callback must be the one which is used for whichever
54+
credentials are returned (the RFC leaves this open, but servers in
55+
practice behave this way).
56+
57+
The credentials are returned using the same pattern which libgit2 uses
58+
for its API: the first parameter is an output parameter and the `int`
59+
return value determines success or failure. A typicall callback would
60+
hand off control to the UI (or other retrieval method) to gather
61+
information and then chain the return code to one of the credential
62+
object's constructors. For example, if an application is only
63+
interested in supporting user/password authentication, it can do something like:
64+
65+
```C
66+
int credentials_cb(git_cred **out, const char *url, const char *username_from_url,
67+
unsigned int allowed_types, void *payload)
68+
{
69+
int error;
70+
const char *user, *pass;
71+
72+
/*
73+
* Ask the user via the UI. On error, store the information and return GIT_EUSER which will be
74+
* bubbled up to the code performing the fetch or push. Using GIT_EUSER allows the application
75+
* to know it was an error from the application instead of libgit2.
76+
*/
77+
if ((error = ask_user(&user, &pass, url, username_from_url, allowed_types)) < 0) {
78+
store_error(error);
79+
return GIT_EUSER;
80+
}
81+
82+
return git_cred_plaintext_new(out, user, pass);
83+
}
84+
```

docs/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ This is the place for information on how to get started, best practices, and in-
1010

1111
* [Complete guide to linking](guides/build-and-link) on various platforms.
1212
* [101 samples](guides/101-samples) for doing all kinds of things.
13+
* [Network authentication](guides/authentication) against Git servers.
1314

1415
## Annotated Examples
1516

0 commit comments

Comments
 (0)