Skip to content

Commit f1665a5

Browse files
committed
tests: online: consolidate online::clone::env test suite
1 parent 1875a04 commit f1665a5

2 files changed

Lines changed: 80 additions & 153 deletions

File tree

azure-pipelines/test.sh

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,6 @@ if [ -z "$SKIP_SSH_TESTS" ]; then
219219
export GITTEST_REMOTE_URL="ssh://localhost:2222/$SSHD_DIR/test.git"
220220
export GITTEST_REMOTE_USER=$USER
221221
export GITTEST_REMOTE_PASS=$PASSWORD
222-
export GITTEST_REMOTE_SSL_NOVERIFY=1
223222
export GITTEST_REMOTE_SSH_KEY="${HOME}/.ssh/id_rsa"
224223
export GITTEST_REMOTE_SSH_PUBKEY="${HOME}/.ssh/id_rsa.pub"
225224
export GITTEST_REMOTE_SSH_PASSPHRASE=""
@@ -228,7 +227,6 @@ if [ -z "$SKIP_SSH_TESTS" ]; then
228227
unset GITTEST_REMOTE_URL
229228
unset GITTEST_REMOTE_USER
230229
unset GITTEST_REMOTE_PASS
231-
unset GITTEST_REMOTE_SSL_NOVERIFY
232230
unset GITTEST_REMOTE_SSH_KEY
233231
unset GITTEST_REMOTE_SSH_PUBKEY
234232
unset GITTEST_REMOTE_SSH_PASSPHRASE

tests/online/clone/env.c

Lines changed: 80 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "git2/clone.h"
44
#include "git2/cred_helpers.h"
55
#include "git2/sys/transport.h"
6+
#include "futils.h"
67

78
#define CLONE_PATH "./foo"
89

@@ -13,36 +14,96 @@ static char *_remote_url = NULL;
1314
static char *_remote_user = NULL;
1415
static char *_remote_pass = NULL;
1516

16-
static char *_remote_sslnoverify = NULL;
1717
static char *_remote_ssh_pubkey = NULL;
1818
static char *_remote_ssh_privkey = NULL;
1919
static char *_remote_ssh_passphrase = NULL;
2020
static char *_remote_ssh_fingerprint = NULL;
2121

22+
static struct {
23+
unsigned int allowed_types;
24+
} credentials_cb_opts;
25+
2226
static int certificate_check_cb(git_cert *cert, int valid, const char *host, void *payload)
2327
{
24-
GIT_UNUSED(cert);
2528
GIT_UNUSED(host);
29+
GIT_UNUSED(valid);
2630
GIT_UNUSED(payload);
2731

28-
if (_remote_sslnoverify != NULL)
29-
valid = 1;
32+
if (_remote_ssh_fingerprint && cert->cert_type == GIT_CERT_HOSTKEY_LIBSSH2) {
33+
git_cert_hostkey *key = (git_cert_hostkey *) cert;
34+
git_oid expected;
35+
36+
cl_git_pass(git_oid_fromstrp(&expected, _remote_ssh_fingerprint));
37+
38+
/*
39+
* We need to figure out how long our input was to check for
40+
* the type. Here we abuse the fact that both hashes fit into
41+
* our git_oid type.
42+
*/
43+
if (strlen(_remote_ssh_fingerprint) == 32 && key->type & GIT_CERT_SSH_MD5) {
44+
return (memcmp(expected.id, key->hash_md5, 16) == 0) ? 0 : -1;
45+
} else if (strlen(_remote_ssh_fingerprint) == 40 && key->type & GIT_CERT_SSH_SHA1) {
46+
return (memcmp(expected.id, key->hash_sha1, 20) == 0) ? 0 : -1;
47+
}
48+
}
49+
50+
return -1;
51+
}
52+
53+
static int credentials_cb(git_cred **cred, const char *url, const char *user_from_url,
54+
unsigned int allowed_types, void *_payload)
55+
{
56+
GIT_UNUSED(url);
57+
GIT_UNUSED(user_from_url);
58+
GIT_UNUSED(_payload);
59+
60+
if (credentials_cb_opts.allowed_types)
61+
allowed_types &= credentials_cb_opts.allowed_types;
3062

63+
if (allowed_types & GIT_CREDTYPE_USERNAME && _remote_user)
64+
return git_cred_username_new(cred, _remote_user);
65+
66+
if (allowed_types & GIT_CREDTYPE_USERPASS_PLAINTEXT && _remote_user && _remote_pass)
67+
return git_cred_userpass_plaintext_new(cred, _remote_user, _remote_pass);
68+
69+
if (allowed_types & GIT_CREDTYPE_SSH_KEY && _remote_ssh_pubkey && _remote_ssh_privkey) {
70+
return git_cred_ssh_key_new(cred, _remote_user, _remote_ssh_pubkey,
71+
_remote_ssh_privkey, _remote_ssh_passphrase);
72+
}
73+
74+
if (allowed_types & GIT_CREDTYPE_SSH_MEMORY && _remote_ssh_pubkey && _remote_ssh_privkey) {
75+
git_buf pubkey = GIT_BUF_INIT, privkey = GIT_BUF_INIT;
76+
int error;
77+
78+
cl_git_pass(git_futils_readbuffer(&pubkey, _remote_ssh_pubkey));
79+
cl_git_pass(git_futils_readbuffer(&privkey, _remote_ssh_privkey));
80+
81+
error = git_cred_ssh_key_memory_new(cred, _remote_user, pubkey.ptr,
82+
privkey.ptr, _remote_ssh_passphrase);
83+
84+
git_buf_dispose(&pubkey);
85+
git_buf_dispose(&privkey);
86+
87+
return error;
88+
}
3189

32-
return valid ? 0 : GIT_ECERTIFICATE;
90+
git_error_set(GIT_ERROR_NET, "unexpected cred type");
91+
return -1;
3392
}
3493

3594
void test_online_clone_env__initialize(void)
3695
{
3796
git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
3897

98+
memset(&credentials_cb_opts, 0, sizeof(credentials_cb_opts));
99+
39100
memcpy(&g_options, &opts, sizeof(g_options));
40101
g_options.fetch_opts.callbacks.certificate_check = certificate_check_cb;
102+
g_options.fetch_opts.callbacks.credentials = credentials_cb;
41103

42104
_remote_url = cl_getenv("GITTEST_REMOTE_URL");
43105
_remote_user = cl_getenv("GITTEST_REMOTE_USER");
44106
_remote_pass = cl_getenv("GITTEST_REMOTE_PASS");
45-
_remote_sslnoverify = cl_getenv("GITTEST_REMOTE_SSL_NOVERIFY");
46107
_remote_ssh_pubkey = cl_getenv("GITTEST_REMOTE_SSH_PUBKEY");
47108
_remote_ssh_privkey = cl_getenv("GITTEST_REMOTE_SSH_KEY");
48109
_remote_ssh_passphrase = cl_getenv("GITTEST_REMOTE_SSH_PASSPHRASE");
@@ -58,70 +119,21 @@ void test_online_clone_env__cleanup(void)
58119
git__free(_remote_url);
59120
git__free(_remote_user);
60121
git__free(_remote_pass);
61-
git__free(_remote_sslnoverify);
62122
git__free(_remote_ssh_pubkey);
63123
git__free(_remote_ssh_privkey);
64124
git__free(_remote_ssh_passphrase);
65125
git__free(_remote_ssh_fingerprint);
66126
}
67127

68-
int cred_default(
69-
git_cred **cred,
70-
const char *url,
71-
const char *user_from_url,
72-
unsigned int allowed_types,
73-
void *payload)
128+
void test_online_clone_env__userpass_authentication(void)
74129
{
75-
GIT_UNUSED(url);
76-
GIT_UNUSED(user_from_url);
77-
GIT_UNUSED(payload);
78-
79-
if (!(allowed_types & GIT_CREDTYPE_DEFAULT))
80-
return 0;
81-
82-
return git_cred_default_new(cred);
83-
}
84-
85-
void test_online_clone_env__credentials(void)
86-
{
87-
/* Remote URL environment variable must be set.
88-
* User and password are optional.
89-
*/
90-
git_cred_userpass_payload user_pass = {
91-
_remote_user,
92-
_remote_pass
93-
};
94-
95130
if (!_remote_url)
96131
clar__skip();
97132

98-
if (cl_is_env_set("GITTEST_REMOTE_DEFAULT")) {
99-
g_options.fetch_opts.callbacks.credentials = cred_default;
100-
} else {
101-
g_options.fetch_opts.callbacks.credentials = git_cred_userpass;
102-
g_options.fetch_opts.callbacks.payload = &user_pass;
103-
}
104-
133+
credentials_cb_opts.allowed_types = GIT_CREDTYPE_USERPASS_PLAINTEXT|GIT_CREDTYPE_USERNAME;
105134
cl_git_pass(git_clone(&g_repo, _remote_url, CLONE_PATH, &g_options));
106135
}
107136

108-
static int cred_cb(git_cred **cred, const char *url, const char *user_from_url,
109-
unsigned int allowed_types, void *payload)
110-
{
111-
GIT_UNUSED(url); GIT_UNUSED(user_from_url); GIT_UNUSED(payload);
112-
113-
if (allowed_types & GIT_CREDTYPE_USERNAME)
114-
return git_cred_username_new(cred, _remote_user);
115-
116-
if (allowed_types & GIT_CREDTYPE_SSH_KEY)
117-
return git_cred_ssh_key_new(cred,
118-
_remote_user, _remote_ssh_pubkey,
119-
_remote_ssh_privkey, _remote_ssh_passphrase);
120-
121-
git_error_set(GIT_ERROR_NET, "unexpected cred type");
122-
return -1;
123-
}
124-
125137
static int custom_remote_ssh_with_paths(
126138
git_remote **out,
127139
git_repository *repo,
@@ -155,14 +167,12 @@ void test_online_clone_env__ssh_with_paths(void)
155167
};
156168

157169
#ifndef GIT_SSH
158-
clar__skip();
159-
#endif
160170
if (!_remote_url || !_remote_user || strncmp(_remote_url, "ssh://", 5) != 0)
171+
#endif
161172
clar__skip();
162173

163174
g_options.remote_cb = custom_remote_ssh_with_paths;
164175
g_options.fetch_opts.callbacks.transport = git_transport_ssh_with_paths;
165-
g_options.fetch_opts.callbacks.credentials = cred_cb;
166176
g_options.fetch_opts.callbacks.payload = &arr;
167177
g_options.fetch_opts.callbacks.certificate_check = NULL;
168178

@@ -172,105 +182,24 @@ void test_online_clone_env__ssh_with_paths(void)
172182
cl_git_pass(git_clone(&g_repo, _remote_url, CLONE_PATH, &g_options));
173183
}
174184

175-
static int ssh_certificate_check(git_cert *cert, int valid, const char *host, void *payload)
176-
{
177-
git_cert_hostkey *key;
178-
git_oid expected = {{0}}, actual = {{0}};
179-
180-
GIT_UNUSED(valid);
181-
GIT_UNUSED(payload);
182-
183-
cl_assert(_remote_ssh_fingerprint);
184-
185-
cl_git_pass(git_oid_fromstrp(&expected, _remote_ssh_fingerprint));
186-
cl_assert_equal_i(GIT_CERT_HOSTKEY_LIBSSH2, cert->cert_type);
187-
key = (git_cert_hostkey *) cert;
188-
189-
/*
190-
* We need to figure out how long our input was to check for
191-
* the type. Here we abuse the fact that both hashes fit into
192-
* our git_oid type.
193-
*/
194-
if (strlen(_remote_ssh_fingerprint) == 32 && key->type & GIT_CERT_SSH_MD5) {
195-
memcpy(&actual.id, key->hash_md5, 16);
196-
} else if (strlen(_remote_ssh_fingerprint) == 40 && key->type & GIT_CERT_SSH_SHA1) {
197-
memcpy(&actual, key->hash_sha1, 20);
198-
} else {
199-
cl_fail("Cannot find a usable SSH hash");
200-
}
201-
202-
cl_assert(!memcmp(&expected, &actual, 20));
203-
204-
cl_assert_equal_s("localhost", host);
205-
206-
return GIT_EUSER;
207-
}
208-
209-
void test_online_clone_env__ssh_cert(void)
210-
{
211-
g_options.fetch_opts.callbacks.certificate_check = ssh_certificate_check;
212-
213-
if (!_remote_ssh_fingerprint)
214-
cl_skip();
215-
216-
cl_git_fail_with(GIT_EUSER, git_clone(&g_repo, _remote_url, CLONE_PATH, &g_options));
217-
}
218-
219-
static char *read_key_file(const char *path)
220-
{
221-
FILE *f;
222-
char *buf;
223-
long key_length;
224-
225-
if (!path || !*path)
226-
return NULL;
227-
228-
cl_assert((f = fopen(path, "r")) != NULL);
229-
cl_assert(fseek(f, 0, SEEK_END) != -1);
230-
cl_assert((key_length = ftell(f)) != -1);
231-
cl_assert(fseek(f, 0, SEEK_SET) != -1);
232-
cl_assert((buf = malloc(key_length)) != NULL);
233-
cl_assert(fread(buf, key_length, 1, f) == 1);
234-
fclose(f);
235-
236-
return buf;
237-
}
238-
239-
static int ssh_memory_cred_cb(git_cred **cred, const char *url, const char *user_from_url,
240-
unsigned int allowed_types, void *payload)
185+
void test_online_clone_env__ssh_key_authentication(void)
241186
{
242-
GIT_UNUSED(url); GIT_UNUSED(user_from_url); GIT_UNUSED(payload);
243-
244-
if (allowed_types & GIT_CREDTYPE_USERNAME)
245-
return git_cred_username_new(cred, _remote_user);
246-
247-
if (allowed_types & GIT_CREDTYPE_SSH_KEY)
248-
{
249-
char *pubkey = read_key_file(_remote_ssh_pubkey);
250-
char *privkey = read_key_file(_remote_ssh_privkey);
251-
252-
int ret = git_cred_ssh_key_memory_new(cred, _remote_user, pubkey, privkey, _remote_ssh_passphrase);
253-
254-
if (privkey)
255-
free(privkey);
256-
if (pubkey)
257-
free(pubkey);
258-
return ret;
259-
}
187+
#ifndef GIT_SSH
188+
if (!_remote_url || !_remote_user || !_remote_ssh_privkey || strncmp(_remote_url, "ssh://", 5) != 0)
189+
#endif
190+
clar__skip();
260191

261-
git_error_set(GIT_ERROR_NET, "unexpected cred type");
262-
return -1;
192+
credentials_cb_opts.allowed_types = GIT_CREDTYPE_SSH_KEY|GIT_CREDTYPE_USERNAME;
193+
cl_git_pass(git_clone(&g_repo, _remote_url, CLONE_PATH, &g_options));
263194
}
264195

265-
void test_online_clone_env__ssh_memory_auth(void)
196+
void test_online_clone_env__ssh_inmemory_authentication(void)
266197
{
267198
#ifndef GIT_SSH_MEMORY_CREDENTIALS
268-
clar__skip();
269-
#endif
270199
if (!_remote_url || !_remote_user || !_remote_ssh_privkey || strncmp(_remote_url, "ssh://", 5) != 0)
200+
#endif
271201
clar__skip();
272202

273-
g_options.fetch_opts.callbacks.credentials = ssh_memory_cred_cb;
274-
203+
credentials_cb_opts.allowed_types = GIT_CREDTYPE_SSH_MEMORY|GIT_CREDTYPE_USERNAME;
275204
cl_git_pass(git_clone(&g_repo, _remote_url, CLONE_PATH, &g_options));
276205
}

0 commit comments

Comments
 (0)