]> git.proxmox.com Git - libgit2.git/blame - src/transports/credential.c
New upstream version 1.3.0+dfsg.1
[libgit2.git] / src / transports / credential.c
CommitLineData
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
14static 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
22int git_credential_has_username(git_credential *cred)
23{
24 if (cred->credtype == GIT_CREDENTIAL_DEFAULT)
25 return 0;
26
27 return 1;
28}
29
30const 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
65static 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
81int 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
116static 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
147static 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
156static 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
172static void default_free(struct git_credential *cred)
173{
174 git_credential_default *c = (git_credential_default *)cred;
175
176 git__free(c);
177}
178
179static void username_free(struct git_credential *cred)
180{
181 git__free(cred);
182}
183
184int 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
200int 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
228static 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
268int 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
296int 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
317int 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
354int 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
370int 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
392void 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
403int git_cred_has_username(git_credential *cred)
404{
405 return git_credential_has_username(cred);
406}
407
408const char *git_cred_get_username(git_credential *cred)
409{
410 return git_credential_get_username(cred);
411}
412
413int 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
421int git_cred_default_new(git_credential **out)
422{
423 return git_credential_default_new(out);
424}
425
426int git_cred_username_new(git_credential **out, const char *username)
427{
428 return git_credential_username_new(out, username);
429}
430
431int 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
442int 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
453int 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
463int 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
470int 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
482void git_cred_free(git_credential *cred)
483{
484 git_credential_free(cred);
485}
486#endif