Skip to content

Commit 208932b

Browse files
committed
now able to clone from ssh using a SSH key
1 parent 8237102 commit 208932b

File tree

7 files changed

+168
-4
lines changed

7 files changed

+168
-4
lines changed

git2_cred.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,25 @@ typedef struct _git2_cred_object {
1414
ZEND_BEGIN_ARG_INFO_EX(arginfo_cred_create_default, 0, 0, 0)
1515
ZEND_END_ARG_INFO()
1616

17+
git_cred *git2_cred_extract_from_zval(zval *zv) {
18+
if (Z_TYPE_P(zv) != IS_OBJECT) return NULL;
19+
if (Z_OBJCE_P(zv) != php_git2_cred_ce) return NULL;
20+
21+
git2_cred_object_t *intern = (git2_cred_object_t*)Z_OBJ_P(zv);
22+
return intern->cred;
23+
}
24+
25+
git_cred *git2_cred_take_from_zval(zval *zv) {
26+
git_cred *cred;
27+
if (Z_TYPE_P(zv) != IS_OBJECT) return NULL;
28+
if (Z_OBJCE_P(zv) != php_git2_cred_ce) return NULL;
29+
30+
git2_cred_object_t *intern = (git2_cred_object_t*)Z_OBJ_P(zv);
31+
cred = intern->cred;
32+
intern->cred = NULL;
33+
return cred;
34+
}
35+
1736
static PHP_METHOD(Cred, create_default) {
1837
if (zend_parse_parameters_none() == FAILURE) return;
1938
git2_cred_object_t *intern;

git2_cred.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,7 @@ void git2_cred_init(TSRMLS_DC);
55

66
void git2_cred_spawn(zval *return_value, git_cred *cred TSRMLS_DC);
77

8+
git_cred *git2_cred_extract_from_zval(zval *o);
9+
git_cred *git2_cred_take_from_zval(zval *o);
10+
811
#endif /* GIT2_CRED_H */

git2_php_util.c

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "php_git2.h"
22
#include "git2_php_util.h"
3+
#include "git2_cred.h"
34

45
#define ARRAY_FETCH_LONG(_x) if ((data = zend_hash_str_find(ht, ZEND_STRL(#_x))) != NULL) { \
56
convert_to_long(data); \
@@ -23,7 +24,74 @@
2324

2425
#define ARRAY_FETCH_STRARRAY(_x) ARRAY_FETCH_OPTIONS(_x, php_git2_ht_to_strarray)
2526

26-
#define ARRAY_FETCH_CALLBACK(_x, _payload) /* TODO */
27+
#define ARRAY_FETCH_CALLBACK(_x, _payload) if ((data = zend_hash_str_find(ht, ZEND_STRL(#_x))) != NULL) { \
28+
git2_callback_ ## _x ## _set(&opts->_x, &opts->_payload, data); \
29+
}
30+
31+
// all remote callbacks have the same payload, so this makes a large structure
32+
struct git2_remote_callbacks_payload {
33+
zval *credentials_callback;
34+
zend_fcall_info_cache fci_cache;
35+
};
36+
37+
int git2_callback_credentials_call(git_cred **cred, const char *url, const char *username_from_url, unsigned int allowed_types, void *payload) {
38+
struct git2_remote_callbacks_payload *p = (struct git2_remote_callbacks_payload*)payload;
39+
if (p->credentials_callback == NULL) return 1; // ??
40+
41+
zend_fcall_info fci;
42+
zval argv[3];
43+
zval retval;
44+
int error;
45+
46+
ZVAL_STRING(&argv[0], url);
47+
ZVAL_STRING(&argv[1], username_from_url);
48+
ZVAL_LONG(&argv[2], allowed_types);
49+
50+
fci.size = sizeof(fci);
51+
fci.function_table = EG(function_table);
52+
fci.object = NULL;
53+
ZVAL_COPY_VALUE(&fci.function_name, p->credentials_callback);
54+
fci.retval = &retval;
55+
fci.param_count = 3;
56+
fci.params = argv;
57+
fci.no_separation = 0;
58+
fci.symbol_table = NULL;
59+
60+
error = zend_call_function(&fci, &p->fci_cache);
61+
62+
zval_ptr_dtor(&argv[0]);
63+
zval_ptr_dtor(&argv[1]);
64+
zval_ptr_dtor(&argv[2]);
65+
66+
if (error == FAILURE) {
67+
php_error_docref(NULL, E_WARNING, "Callback for git credentials failed");
68+
return -1;
69+
} else if (!Z_ISUNDEF(retval)) {
70+
git_cred *c = git2_cred_take_from_zval(&retval); // will return NULL if not a cred object or used more than once
71+
if (c) {
72+
*cred = c;
73+
return 0;
74+
}
75+
return 1;
76+
} else {
77+
return 1;
78+
}
79+
}
80+
81+
static void git2_callback_credentials_set(git_cred_acquire_cb *cb, void **payload, zval *callback) {
82+
struct git2_remote_callbacks_payload *p;
83+
if (*payload == NULL) {
84+
*payload = emalloc(sizeof(struct git2_remote_callbacks_payload));
85+
memset(*payload, 0, sizeof(struct git2_remote_callbacks_payload));
86+
p = (struct git2_remote_callbacks_payload*)*payload;
87+
p->fci_cache = empty_fcall_info_cache;
88+
} else {
89+
p = (struct git2_remote_callbacks_payload*)*payload;
90+
}
91+
92+
p->credentials_callback = callback;
93+
*cb = git2_callback_credentials_call;
94+
}
2795

2896
void php_git2_ht_to_strarray(git_strarray *out, HashTable *in) {
2997
uint32_t count = zend_array_count(in);

git2_tests/002_clone_ssh.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
$tmp = sys_get_temp_dir().'/php-git2_test_ssh';
4+
5+
if (file_exists($tmp)) {
6+
echo "Skipping test - Remove $tmp to run test - rm -fr ".escapeshellarg($tmp)."\n";
7+
exit(0); // skip test
8+
}
9+
10+
$options = [
11+
'fetch_opts' => [
12+
'callbacks' => [
13+
'credentials' => function($url, $username, $types) {
14+
return Git2\Cred::create_ssh_key($username, __DIR__.'/test_key.pub', __DIR__.'/test_key');
15+
},
16+
],
17+
],
18+
];
19+
20+
echo "Cloning repository...\n";
21+
$repo = Git2\Repository::clone('git@github.com:MagicalTux/php-git2.git', $tmp, $options);
22+
23+
#var_dump($repo->checkout_head());
24+
var_dump($repo->head());
25+

git2_tests/test_key

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
-----BEGIN RSA PRIVATE KEY-----
2+
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
51+
-----END RSA PRIVATE KEY-----

git2_tests/test_key.pub

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC3A7jr8JMIXQa05SsbjdhJ7ZSvYJ/LpAu/j1k210YLy4+9vqBh7PXBIwL5Af5Fg5oeq2iZkmvO8ATMpLYPS/UmjsLwmEtlkhFj7oOUcdKMhDOS9j+A1LHkNd4wPwR5/FhffMtRQIJcJXVpuV02KbkMPvNhl/4KhJREdSvKRtSBEpJBaqJTkLKJQ9E3lnos0LfnmVE9thT69Dk/PZmpN+WSAIcLhp/OPmaaNJrg0lQRa0Vpp0aUfiP39FGSyi+Pc7Ei/6kfSWRZuJvsFNmSzvrQ6AK/Z86JZT7PG2dg6/o72CUFCmg2dKt5rYmB9Yi0Us7EYg8GyOC2ctlDulTYv5poaqgh/3N5KfbUUTAqQuAlq3IZf3pfWv2IZ+Kodf/vNv8b0ludMaHfflE/gJGCm4VLkg3XO/dHll7FzRe8cSyBsuWRRF5KvgO8duiTCWS57WF5hZVXukBqO/z4uDmdtS9Rm/V9MgL84K2DQs25FaKyeil73t+fmEGEK0EdI/6o8mzqTV01jFBWMuOFh554zvnSpTt1uCQ6Q5AT37Xa5PA3Kp0L823qoFkx2/LT2bqLEqeljTThmvxMOFiIjeIaEAmFvUrDbQ7k9mtKcNVE9tuTPqSGQBpKte0cJ0y0P2SiV9StaHdQ75ObOnBhw0bPR8T2JNOnfROEOeeb8KqfKcum1w== test@key

php_git2.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,4 @@ extern zend_module_entry git2_module_entry;
3636
#define PHP_GIT2_API
3737
#endif
3838

39-
//PHP_GIT2_API zend_class_entry *php_git2_get_repository(void);
40-
41-
4239
#endif /* PHP_GIT2_H */

0 commit comments

Comments
 (0)