Skip to content

Commit 8bf0f7e

Browse files
committed
cred: separate public interface from low-level details
1 parent c97cf08 commit 8bf0f7e

File tree

14 files changed

+429
-339
lines changed

14 files changed

+429
-339
lines changed

docs/changelog.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
v0.28 + 1
22
---------
33

4+
### Breaking API changes
5+
6+
* The "private" implementation details of the `git_cred` structure have been
7+
moved to a dedicated `git2/sys/cred.h` header, to clarify that the underlying
8+
structures are only provided for custom transport implementers.
9+
The breaking change is that the `username` member of the underlying struct
10+
is now hidden, and a new `git_cred_get_username` function has been provided.
11+
412
### Breaking CMake configuration changes
513

614
* The CMake option to use a system http-parser library, instead of the

include/git2.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "git2/commit.h"
2222
#include "git2/common.h"
2323
#include "git2/config.h"
24+
#include "git2/cred.h"
2425
#include "git2/deprecated.h"
2526
#include "git2/describe.h"
2627
#include "git2/diff.h"

include/git2/cred.h

Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
1+
/*
2+
* Copyright (C) the libgit2 contributors. All rights reserved.
3+
*
4+
* This file is part of libgit2, distributed under the GNU GPL v2 with
5+
* a Linking Exception. For full terms see the included COPYING file.
6+
*/
7+
#ifndef INCLUDE_git_cred_h__
8+
#define INCLUDE_git_cred_h__
9+
10+
#include "common.h"
11+
12+
/**
13+
* @file git2/cred.h
14+
* @brief Git authentication & credential management
15+
* @defgroup git_cred Authentication & credential management
16+
* @ingroup Git
17+
* @{
18+
*/
19+
GIT_BEGIN_DECL
20+
21+
/**
22+
* Supported credential types
23+
*
24+
* This represents the various types of authentication methods supported by
25+
* the library.
26+
*/
27+
typedef enum {
28+
/**
29+
* A vanilla user/password request
30+
* @see git_cred_userpass_plaintext_new
31+
*/
32+
GIT_CREDTYPE_USERPASS_PLAINTEXT = (1u << 0),
33+
34+
/**
35+
* An SSH key-based authentication request
36+
* @see git_cred_ssh_key_new
37+
*/
38+
GIT_CREDTYPE_SSH_KEY = (1u << 1),
39+
40+
/**
41+
* An SSH key-based authentication request, with a custom signature
42+
* @see git_cred_ssh_custom_new
43+
*/
44+
GIT_CREDTYPE_SSH_CUSTOM = (1u << 2),
45+
46+
/**
47+
* An NTLM/Negotiate-based authentication request.
48+
* @see git_cred_default
49+
*/
50+
GIT_CREDTYPE_DEFAULT = (1u << 3),
51+
52+
/**
53+
* An SSH interactive authentication request
54+
* @see git_cred_ssh_interactive_new
55+
*/
56+
GIT_CREDTYPE_SSH_INTERACTIVE = (1u << 4),
57+
58+
/**
59+
* Username-only authentication request
60+
*
61+
* Used as a pre-authentication step if the underlying transport
62+
* (eg. SSH, with no username in its URL) does not know which username
63+
* to use.
64+
*
65+
* @see git_cred_username_new
66+
*/
67+
GIT_CREDTYPE_USERNAME = (1u << 5),
68+
69+
/**
70+
* An SSH key-based authentication request
71+
*
72+
* Allows credentials to be read from memory instead of files.
73+
* Note that because of differences in crypto backend support, it might
74+
* not be functional.
75+
*
76+
* @see git_cred_ssh_key_memory_new
77+
*/
78+
GIT_CREDTYPE_SSH_MEMORY = (1u << 6),
79+
} git_credtype_t;
80+
81+
/**
82+
* The base structure for all credential types
83+
*/
84+
typedef struct git_cred git_cred;
85+
86+
typedef struct git_cred_userpass_plaintext git_cred_userpass_plaintext;
87+
88+
/** Username-only credential information */
89+
typedef struct git_cred_username git_cred_username;
90+
91+
/** A key for NTLM/Kerberos "default" credentials */
92+
typedef struct git_cred git_cred_default;
93+
94+
/**
95+
* A ssh key from disk
96+
*/
97+
typedef struct git_cred_ssh_key git_cred_ssh_key;
98+
99+
/**
100+
* Keyboard-interactive based ssh authentication
101+
*/
102+
typedef struct git_cred_ssh_interactive git_cred_ssh_interactive;
103+
104+
/**
105+
* A key with a custom signature function
106+
*/
107+
typedef struct git_cred_ssh_custom git_cred_ssh_custom;
108+
109+
/**
110+
* Credential acquisition callback.
111+
*
112+
* This callback is usually involved any time another system might need
113+
* authentication. As such, you are expected to provide a valid git_cred
114+
* object back, depending on allowed_types (a git_credtype_t bitmask).
115+
*
116+
* Note that most authentication details are your responsibility - this
117+
* callback will be called until the authentication succeeds, or you report
118+
* an error. As such, it's easy to get in a loop if you fail to stop providing
119+
* the same incorrect credentials.
120+
*
121+
* @param cred The newly created credential object.
122+
* @param url The resource for which we are demanding a credential.
123+
* @param username_from_url The username that was embedded in a "user\@host"
124+
* remote url, or NULL if not included.
125+
* @param allowed_types A bitmask stating which cred types are OK to return.
126+
* @param payload The payload provided when specifying this callback.
127+
* @return 0 for success, < 0 to indicate an error, > 0 to indicate
128+
* no credential was acquired
129+
*/
130+
typedef int GIT_CALLBACK(git_cred_acquire_cb)(
131+
git_cred **cred,
132+
const char *url,
133+
const char *username_from_url,
134+
unsigned int allowed_types,
135+
void *payload);
136+
137+
/**
138+
* Free a credential.
139+
*
140+
* This is only necessary if you own the object; that is, if you are a
141+
* transport.
142+
*
143+
* @param cred the object to free
144+
*/
145+
GIT_EXTERN(void) git_cred_free(git_cred *cred);
146+
147+
/**
148+
* Check whether a credential object contains username information.
149+
*
150+
* @param cred object to check
151+
* @return 1 if the credential object has non-NULL username, 0 otherwise
152+
*/
153+
GIT_EXTERN(int) git_cred_has_username(git_cred *cred);
154+
155+
/**
156+
* Return the username associated with a credential object.
157+
*
158+
* @param cred object to check
159+
* @return the credential username, or NULL if not applicable
160+
*/
161+
GIT_EXTERN(const char *) git_cred_get_username(git_cred *cred);
162+
163+
/**
164+
* Create a new plain-text username and password credential object.
165+
* The supplied credential parameter will be internally duplicated.
166+
*
167+
* @param out The newly created credential object.
168+
* @param username The username of the credential.
169+
* @param password The password of the credential.
170+
* @return 0 for success or an error code for failure
171+
*/
172+
GIT_EXTERN(int) git_cred_userpass_plaintext_new(
173+
git_cred **out,
174+
const char *username,
175+
const char *password);
176+
177+
/**
178+
* Create a "default" credential usable for Negotiate mechanisms like NTLM
179+
* or Kerberos authentication.
180+
*
181+
* @return 0 for success or an error code for failure
182+
*/
183+
GIT_EXTERN(int) git_cred_default_new(git_cred **out);
184+
185+
/**
186+
* Create a credential to specify a username.
187+
*
188+
* This is used with ssh authentication to query for the username if
189+
* none is specified in the url.
190+
*/
191+
GIT_EXTERN(int) git_cred_username_new(git_cred **cred, const char *username);
192+
193+
/**
194+
* Create a new passphrase-protected ssh key credential object.
195+
* The supplied credential parameter will be internally duplicated.
196+
*
197+
* @param out The newly created credential object.
198+
* @param username username to use to authenticate
199+
* @param publickey The path to the public key of the credential.
200+
* @param privatekey The path to the private key of the credential.
201+
* @param passphrase The passphrase of the credential.
202+
* @return 0 for success or an error code for failure
203+
*/
204+
GIT_EXTERN(int) git_cred_ssh_key_new(
205+
git_cred **out,
206+
const char *username,
207+
const char *publickey,
208+
const char *privatekey,
209+
const char *passphrase);
210+
211+
/**
212+
* Create a new ssh key credential object reading the keys from memory.
213+
*
214+
* @param out The newly created credential object.
215+
* @param username username to use to authenticate.
216+
* @param publickey The public key of the credential.
217+
* @param privatekey The private key of the credential.
218+
* @param passphrase The passphrase of the credential.
219+
* @return 0 for success or an error code for failure
220+
*/
221+
GIT_EXTERN(int) git_cred_ssh_key_memory_new(
222+
git_cred **out,
223+
const char *username,
224+
const char *publickey,
225+
const char *privatekey,
226+
const char *passphrase);
227+
228+
/*
229+
* If the user hasn't included libssh2.h before git2.h, we need to
230+
* define a few types for the callback signatures.
231+
*/
232+
#ifndef LIBSSH2_VERSION
233+
typedef struct _LIBSSH2_SESSION LIBSSH2_SESSION;
234+
typedef struct _LIBSSH2_USERAUTH_KBDINT_PROMPT LIBSSH2_USERAUTH_KBDINT_PROMPT;
235+
typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE LIBSSH2_USERAUTH_KBDINT_RESPONSE;
236+
#endif
237+
238+
typedef void GIT_CALLBACK(git_cred_ssh_interactive_cb)(
239+
const char *name,
240+
int name_len,
241+
const char *instruction, int instruction_len,
242+
int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
243+
LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
244+
void **abstract);
245+
246+
247+
/**
248+
* Create a new ssh keyboard-interactive based credential object.
249+
* The supplied credential parameter will be internally duplicated.
250+
*
251+
* @param username Username to use to authenticate.
252+
* @param prompt_callback The callback method used for prompts.
253+
* @param payload Additional data to pass to the callback.
254+
* @return 0 for success or an error code for failure.
255+
*/
256+
GIT_EXTERN(int) git_cred_ssh_interactive_new(
257+
git_cred **out,
258+
const char *username,
259+
git_cred_ssh_interactive_cb prompt_callback,
260+
void *payload);
261+
262+
/**
263+
* Create a new ssh key credential object used for querying an ssh-agent.
264+
* The supplied credential parameter will be internally duplicated.
265+
*
266+
* @param out The newly created credential object.
267+
* @param username username to use to authenticate
268+
* @return 0 for success or an error code for failure
269+
*/
270+
GIT_EXTERN(int) git_cred_ssh_key_from_agent(
271+
git_cred **out,
272+
const char *username);
273+
274+
typedef int GIT_CALLBACK(git_cred_sign_cb)(
275+
LIBSSH2_SESSION *session,
276+
unsigned char **sig, size_t *sig_len,
277+
const unsigned char *data, size_t data_len,
278+
void **abstract);
279+
280+
/**
281+
* Create an ssh key credential with a custom signing function.
282+
*
283+
* This lets you use your own function to sign the challenge.
284+
*
285+
* This function and its credential type is provided for completeness
286+
* and wraps `libssh2_userauth_publickey()`, which is undocumented.
287+
*
288+
* The supplied credential parameter will be internally duplicated.
289+
*
290+
* @param out The newly created credential object.
291+
* @param username username to use to authenticate
292+
* @param publickey The bytes of the public key.
293+
* @param publickey_len The length of the public key in bytes.
294+
* @param sign_callback The callback method to sign the data during the challenge.
295+
* @param payload Additional data to pass to the callback.
296+
* @return 0 for success or an error code for failure
297+
*/
298+
GIT_EXTERN(int) git_cred_ssh_custom_new(
299+
git_cred **out,
300+
const char *username,
301+
const char *publickey,
302+
size_t publickey_len,
303+
git_cred_sign_cb sign_callback,
304+
void *payload);
305+
306+
/** @} */
307+
GIT_END_DECL
308+
#endif

include/git2/proxy.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#define INCLUDE_git_proxy_h__
99

1010
#include "common.h"
11-
#include "transport.h"
11+
#include "cred.h"
1212

1313
GIT_BEGIN_DECL
1414

0 commit comments

Comments
 (0)