]>
Commit | Line | Data |
---|---|---|
22a2d3d5 UG |
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 | ||
8 | #include "common.h" | |
9 | ||
10 | #include "git2/credential.h" | |
11 | #include "git2/sys/credential.h" | |
12 | #include "git2/credential_helpers.h" | |
13 | ||
14 | static int git_credential_ssh_key_type_new( | |
15 | git_credential **cred, | |
16 | const char *username, | |
17 | const char *publickey, | |
18 | const char *privatekey, | |
19 | const char *passphrase, | |
20 | git_credential_t credtype); | |
21 | ||
22 | int git_credential_has_username(git_credential *cred) | |
23 | { | |
24 | if (cred->credtype == GIT_CREDENTIAL_DEFAULT) | |
25 | return 0; | |
26 | ||
27 | return 1; | |
28 | } | |
29 | ||
30 | const char *git_credential_get_username(git_credential *cred) | |
31 | { | |
32 | switch (cred->credtype) { | |
33 | case GIT_CREDENTIAL_USERNAME: | |
34 | { | |
35 | git_credential_username *c = (git_credential_username *) cred; | |
36 | return c->username; | |
37 | } | |
38 | case GIT_CREDENTIAL_USERPASS_PLAINTEXT: | |
39 | { | |
40 | git_credential_userpass_plaintext *c = (git_credential_userpass_plaintext *) cred; | |
41 | return c->username; | |
42 | } | |
43 | case GIT_CREDENTIAL_SSH_KEY: | |
44 | case GIT_CREDENTIAL_SSH_MEMORY: | |
45 | { | |
46 | git_credential_ssh_key *c = (git_credential_ssh_key *) cred; | |
47 | return c->username; | |
48 | } | |
49 | case GIT_CREDENTIAL_SSH_CUSTOM: | |
50 | { | |
51 | git_credential_ssh_custom *c = (git_credential_ssh_custom *) cred; | |
52 | return c->username; | |
53 | } | |
54 | case GIT_CREDENTIAL_SSH_INTERACTIVE: | |
55 | { | |
56 | git_credential_ssh_interactive *c = (git_credential_ssh_interactive *) cred; | |
57 | return c->username; | |
58 | } | |
59 | ||
60 | default: | |
61 | return NULL; | |
62 | } | |
63 | } | |
64 | ||
65 | static void plaintext_free(struct git_credential *cred) | |
66 | { | |
67 | git_credential_userpass_plaintext *c = (git_credential_userpass_plaintext *)cred; | |
68 | ||
69 | git__free(c->username); | |
70 | ||
71 | /* Zero the memory which previously held the password */ | |
72 | if (c->password) { | |
73 | size_t pass_len = strlen(c->password); | |
74 | git__memzero(c->password, pass_len); | |
75 | git__free(c->password); | |
76 | } | |
77 | ||
78 | git__free(c); | |
79 | } | |
80 | ||
81 | int git_credential_userpass_plaintext_new( | |
82 | git_credential **cred, | |
83 | const char *username, | |
84 | const char *password) | |
85 | { | |
86 | git_credential_userpass_plaintext *c; | |
87 | ||
c25aa7cd PP |
88 | GIT_ASSERT_ARG(cred); |
89 | GIT_ASSERT_ARG(username); | |
90 | GIT_ASSERT_ARG(password); | |
22a2d3d5 UG |
91 | |
92 | c = git__malloc(sizeof(git_credential_userpass_plaintext)); | |
93 | GIT_ERROR_CHECK_ALLOC(c); | |
94 | ||
95 | c->parent.credtype = GIT_CREDENTIAL_USERPASS_PLAINTEXT; | |
96 | c->parent.free = plaintext_free; | |
97 | c->username = git__strdup(username); | |
98 | ||
99 | if (!c->username) { | |
100 | git__free(c); | |
101 | return -1; | |
102 | } | |
103 | ||
104 | c->password = git__strdup(password); | |
105 | ||
106 | if (!c->password) { | |
107 | git__free(c->username); | |
108 | git__free(c); | |
109 | return -1; | |
110 | } | |
111 | ||
112 | *cred = &c->parent; | |
113 | return 0; | |
114 | } | |
115 | ||
116 | static void ssh_key_free(struct git_credential *cred) | |
117 | { | |
118 | git_credential_ssh_key *c = | |
119 | (git_credential_ssh_key *)cred; | |
120 | ||
121 | git__free(c->username); | |
122 | ||
123 | if (c->privatekey) { | |
124 | /* Zero the memory which previously held the private key */ | |
125 | size_t key_len = strlen(c->privatekey); | |
126 | git__memzero(c->privatekey, key_len); | |
127 | git__free(c->privatekey); | |
128 | } | |
129 | ||
130 | if (c->passphrase) { | |
131 | /* Zero the memory which previously held the passphrase */ | |
132 | size_t pass_len = strlen(c->passphrase); | |
133 | git__memzero(c->passphrase, pass_len); | |
134 | git__free(c->passphrase); | |
135 | } | |
136 | ||
137 | if (c->publickey) { | |
138 | /* Zero the memory which previously held the public key */ | |
139 | size_t key_len = strlen(c->publickey); | |
140 | git__memzero(c->publickey, key_len); | |
141 | git__free(c->publickey); | |
142 | } | |
143 | ||
144 | git__free(c); | |
145 | } | |
146 | ||
147 | static void ssh_interactive_free(struct git_credential *cred) | |
148 | { | |
149 | git_credential_ssh_interactive *c = (git_credential_ssh_interactive *)cred; | |
150 | ||
151 | git__free(c->username); | |
152 | ||
153 | git__free(c); | |
154 | } | |
155 | ||
156 | static void ssh_custom_free(struct git_credential *cred) | |
157 | { | |
158 | git_credential_ssh_custom *c = (git_credential_ssh_custom *)cred; | |
159 | ||
160 | git__free(c->username); | |
161 | ||
162 | if (c->publickey) { | |
163 | /* Zero the memory which previously held the publickey */ | |
164 | size_t key_len = strlen(c->publickey); | |
165 | git__memzero(c->publickey, key_len); | |
166 | git__free(c->publickey); | |
167 | } | |
168 | ||
169 | git__free(c); | |
170 | } | |
171 | ||
172 | static void default_free(struct git_credential *cred) | |
173 | { | |
174 | git_credential_default *c = (git_credential_default *)cred; | |
175 | ||
176 | git__free(c); | |
177 | } | |
178 | ||
179 | static void username_free(struct git_credential *cred) | |
180 | { | |
181 | git__free(cred); | |
182 | } | |
183 | ||
184 | int git_credential_ssh_key_new( | |
185 | git_credential **cred, | |
186 | const char *username, | |
187 | const char *publickey, | |
188 | const char *privatekey, | |
189 | const char *passphrase) | |
190 | { | |
191 | return git_credential_ssh_key_type_new( | |
192 | cred, | |
193 | username, | |
194 | publickey, | |
195 | privatekey, | |
196 | passphrase, | |
197 | GIT_CREDENTIAL_SSH_KEY); | |
198 | } | |
199 | ||
200 | int git_credential_ssh_key_memory_new( | |
201 | git_credential **cred, | |
202 | const char *username, | |
203 | const char *publickey, | |
204 | const char *privatekey, | |
205 | const char *passphrase) | |
206 | { | |
207 | #ifdef GIT_SSH_MEMORY_CREDENTIALS | |
208 | return git_credential_ssh_key_type_new( | |
209 | cred, | |
210 | username, | |
211 | publickey, | |
212 | privatekey, | |
213 | passphrase, | |
214 | GIT_CREDENTIAL_SSH_MEMORY); | |
215 | #else | |
216 | GIT_UNUSED(cred); | |
217 | GIT_UNUSED(username); | |
218 | GIT_UNUSED(publickey); | |
219 | GIT_UNUSED(privatekey); | |
220 | GIT_UNUSED(passphrase); | |
221 | ||
222 | git_error_set(GIT_ERROR_INVALID, | |
223 | "this version of libgit2 was not built with ssh memory credentials."); | |
224 | return -1; | |
225 | #endif | |
226 | } | |
227 | ||
228 | static int git_credential_ssh_key_type_new( | |
229 | git_credential **cred, | |
230 | const char *username, | |
231 | const char *publickey, | |
232 | const char *privatekey, | |
233 | const char *passphrase, | |
234 | git_credential_t credtype) | |
235 | { | |
236 | git_credential_ssh_key *c; | |
237 | ||
c25aa7cd PP |
238 | GIT_ASSERT_ARG(username); |
239 | GIT_ASSERT_ARG(cred); | |
240 | GIT_ASSERT_ARG(privatekey); | |
22a2d3d5 UG |
241 | |
242 | c = git__calloc(1, sizeof(git_credential_ssh_key)); | |
243 | GIT_ERROR_CHECK_ALLOC(c); | |
244 | ||
245 | c->parent.credtype = credtype; | |
246 | c->parent.free = ssh_key_free; | |
247 | ||
248 | c->username = git__strdup(username); | |
249 | GIT_ERROR_CHECK_ALLOC(c->username); | |
250 | ||
251 | c->privatekey = git__strdup(privatekey); | |
252 | GIT_ERROR_CHECK_ALLOC(c->privatekey); | |
253 | ||
254 | if (publickey) { | |
255 | c->publickey = git__strdup(publickey); | |
256 | GIT_ERROR_CHECK_ALLOC(c->publickey); | |
257 | } | |
258 | ||
259 | if (passphrase) { | |
260 | c->passphrase = git__strdup(passphrase); | |
261 | GIT_ERROR_CHECK_ALLOC(c->passphrase); | |
262 | } | |
263 | ||
264 | *cred = &c->parent; | |
265 | return 0; | |
266 | } | |
267 | ||
268 | int git_credential_ssh_interactive_new( | |
269 | git_credential **out, | |
270 | const char *username, | |
271 | git_credential_ssh_interactive_cb prompt_callback, | |
272 | void *payload) | |
273 | { | |
274 | git_credential_ssh_interactive *c; | |
275 | ||
c25aa7cd PP |
276 | GIT_ASSERT_ARG(out); |
277 | GIT_ASSERT_ARG(username); | |
278 | GIT_ASSERT_ARG(prompt_callback); | |
22a2d3d5 UG |
279 | |
280 | c = git__calloc(1, sizeof(git_credential_ssh_interactive)); | |
281 | GIT_ERROR_CHECK_ALLOC(c); | |
282 | ||
283 | c->parent.credtype = GIT_CREDENTIAL_SSH_INTERACTIVE; | |
284 | c->parent.free = ssh_interactive_free; | |
285 | ||
286 | c->username = git__strdup(username); | |
287 | GIT_ERROR_CHECK_ALLOC(c->username); | |
288 | ||
289 | c->prompt_callback = prompt_callback; | |
290 | c->payload = payload; | |
291 | ||
292 | *out = &c->parent; | |
293 | return 0; | |
294 | } | |
295 | ||
296 | int git_credential_ssh_key_from_agent(git_credential **cred, const char *username) { | |
297 | git_credential_ssh_key *c; | |
298 | ||
c25aa7cd PP |
299 | GIT_ASSERT_ARG(username); |
300 | GIT_ASSERT_ARG(cred); | |
22a2d3d5 UG |
301 | |
302 | c = git__calloc(1, sizeof(git_credential_ssh_key)); | |
303 | GIT_ERROR_CHECK_ALLOC(c); | |
304 | ||
305 | c->parent.credtype = GIT_CREDENTIAL_SSH_KEY; | |
306 | c->parent.free = ssh_key_free; | |
307 | ||
308 | c->username = git__strdup(username); | |
309 | GIT_ERROR_CHECK_ALLOC(c->username); | |
310 | ||
311 | c->privatekey = NULL; | |
312 | ||
313 | *cred = &c->parent; | |
314 | return 0; | |
315 | } | |
316 | ||
317 | int git_credential_ssh_custom_new( | |
318 | git_credential **cred, | |
319 | const char *username, | |
320 | const char *publickey, | |
321 | size_t publickey_len, | |
322 | git_credential_sign_cb sign_callback, | |
323 | void *payload) | |
324 | { | |
325 | git_credential_ssh_custom *c; | |
326 | ||
c25aa7cd PP |
327 | GIT_ASSERT_ARG(username); |
328 | GIT_ASSERT_ARG(cred); | |
22a2d3d5 UG |
329 | |
330 | c = git__calloc(1, sizeof(git_credential_ssh_custom)); | |
331 | GIT_ERROR_CHECK_ALLOC(c); | |
332 | ||
333 | c->parent.credtype = GIT_CREDENTIAL_SSH_CUSTOM; | |
334 | c->parent.free = ssh_custom_free; | |
335 | ||
336 | c->username = git__strdup(username); | |
337 | GIT_ERROR_CHECK_ALLOC(c->username); | |
338 | ||
339 | if (publickey_len > 0) { | |
340 | c->publickey = git__malloc(publickey_len); | |
341 | GIT_ERROR_CHECK_ALLOC(c->publickey); | |
342 | ||
343 | memcpy(c->publickey, publickey, publickey_len); | |
344 | } | |
345 | ||
346 | c->publickey_len = publickey_len; | |
347 | c->sign_callback = sign_callback; | |
348 | c->payload = payload; | |
349 | ||
350 | *cred = &c->parent; | |
351 | return 0; | |
352 | } | |
353 | ||
354 | int git_credential_default_new(git_credential **cred) | |
355 | { | |
356 | git_credential_default *c; | |
357 | ||
c25aa7cd | 358 | GIT_ASSERT_ARG(cred); |
22a2d3d5 UG |
359 | |
360 | c = git__calloc(1, sizeof(git_credential_default)); | |
361 | GIT_ERROR_CHECK_ALLOC(c); | |
362 | ||
363 | c->credtype = GIT_CREDENTIAL_DEFAULT; | |
364 | c->free = default_free; | |
365 | ||
366 | *cred = c; | |
367 | return 0; | |
368 | } | |
369 | ||
370 | int git_credential_username_new(git_credential **cred, const char *username) | |
371 | { | |
372 | git_credential_username *c; | |
373 | size_t len, allocsize; | |
374 | ||
c25aa7cd | 375 | GIT_ASSERT_ARG(cred); |
22a2d3d5 UG |
376 | |
377 | len = strlen(username); | |
378 | ||
379 | GIT_ERROR_CHECK_ALLOC_ADD(&allocsize, sizeof(git_credential_username), len); | |
380 | GIT_ERROR_CHECK_ALLOC_ADD(&allocsize, allocsize, 1); | |
381 | c = git__malloc(allocsize); | |
382 | GIT_ERROR_CHECK_ALLOC(c); | |
383 | ||
384 | c->parent.credtype = GIT_CREDENTIAL_USERNAME; | |
385 | c->parent.free = username_free; | |
386 | memcpy(c->username, username, len + 1); | |
387 | ||
388 | *cred = (git_credential *) c; | |
389 | return 0; | |
390 | } | |
391 | ||
392 | void git_credential_free(git_credential *cred) | |
393 | { | |
394 | if (!cred) | |
395 | return; | |
396 | ||
397 | cred->free(cred); | |
398 | } | |
399 | ||
400 | /* Deprecated credential functions */ | |
401 | ||
402 | #ifndef GIT_DEPRECATE_HARD | |
403 | int git_cred_has_username(git_credential *cred) | |
404 | { | |
405 | return git_credential_has_username(cred); | |
406 | } | |
407 | ||
408 | const char *git_cred_get_username(git_credential *cred) | |
409 | { | |
410 | return git_credential_get_username(cred); | |
411 | } | |
412 | ||
413 | int git_cred_userpass_plaintext_new( | |
414 | git_credential **out, | |
415 | const char *username, | |
416 | const char *password) | |
417 | { | |
418 | return git_credential_userpass_plaintext_new(out,username, password); | |
419 | } | |
420 | ||
421 | int git_cred_default_new(git_credential **out) | |
422 | { | |
423 | return git_credential_default_new(out); | |
424 | } | |
425 | ||
426 | int git_cred_username_new(git_credential **out, const char *username) | |
427 | { | |
428 | return git_credential_username_new(out, username); | |
429 | } | |
430 | ||
431 | int git_cred_ssh_key_new( | |
432 | git_credential **out, | |
433 | const char *username, | |
434 | const char *publickey, | |
435 | const char *privatekey, | |
436 | const char *passphrase) | |
437 | { | |
438 | return git_credential_ssh_key_new(out, username, | |
439 | publickey, privatekey, passphrase); | |
440 | } | |
441 | ||
442 | int git_cred_ssh_key_memory_new( | |
443 | git_credential **out, | |
444 | const char *username, | |
445 | const char *publickey, | |
446 | const char *privatekey, | |
447 | const char *passphrase) | |
448 | { | |
449 | return git_credential_ssh_key_memory_new(out, username, | |
450 | publickey, privatekey, passphrase); | |
451 | } | |
452 | ||
453 | int git_cred_ssh_interactive_new( | |
454 | git_credential **out, | |
455 | const char *username, | |
456 | git_credential_ssh_interactive_cb prompt_callback, | |
457 | void *payload) | |
458 | { | |
459 | return git_credential_ssh_interactive_new(out, username, | |
460 | prompt_callback, payload); | |
461 | } | |
462 | ||
463 | int git_cred_ssh_key_from_agent( | |
464 | git_credential **out, | |
465 | const char *username) | |
466 | { | |
467 | return git_credential_ssh_key_from_agent(out, username); | |
468 | } | |
469 | ||
470 | int git_cred_ssh_custom_new( | |
471 | git_credential **out, | |
472 | const char *username, | |
473 | const char *publickey, | |
474 | size_t publickey_len, | |
475 | git_credential_sign_cb sign_callback, | |
476 | void *payload) | |
477 | { | |
478 | return git_credential_ssh_custom_new(out, username, | |
479 | publickey, publickey_len, sign_callback, payload); | |
480 | } | |
481 | ||
482 | void git_cred_free(git_credential *cred) | |
483 | { | |
484 | git_credential_free(cred); | |
485 | } | |
486 | #endif |