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