view release on metacpan or search on metacpan
+ add_conflict
+ get_conflict
+ merge
- Added Index::Entry methods (Beta) (GH#146):
+ clone
- Added Merge::File::Result methods (Beta) (GH#146):
+ automergeable
+ content
+ path
- The supported authentication types are now supplied to the Remote's
credentials callback.
- Update libgit2 to 4c53489 (GH#147)
- Removed Remote methods (GH#147) (Incompatible change):
+ check_cert()
- Added Remote certificate callback (GH#148)
0.46 2014-09-19 12:42:13+02:00 Africa/Johannesburg
- Fix more test cases that were failing if diff.mnemonicprefix is set (GH#143)
- Revert previous attempt at getting WinHTTP to work
- Fix build with glibc < 2.17
0.25 2013-10-09 15:17:56 Europe/Rome
- Update to libgit2 711333e
+ Rename Branch -> tracking() to upstream() (incompatible change)
+ Rename Remote -> fetchspec() to add_fetch and pushspec to add_push()
They will not return the remote spec anymore (incompatible change)
- Enable support for libssh2 at build-time
- Add support for SSH key credentials via Cred -> keyfile()
- Add Remote -> callbacks() method
- Add Remote -> load() method
0.24 2013-03-31 13:06:30 Europe/Rome
- Update libgit2 to d2a4a54
- Config -> bool()/int()/str() now return undef when a configuration variable
is not found, instead of segfaulting (GH#13)
0.23 2013-03-25 14:09:09 Europe/Rome
}
}
PUTBACK;
FREETMPS;
LEAVE;
return rv;
}
STATIC int git_credentials_cbb(git_cred **cred, const char *url,
const char *usr_from_url, unsigned int allow, void *cbs) {
dSP;
int rv = 0;
AV *types = newAV();
Cred creds;
if (allow & GIT_CREDTYPE_USERPASS_PLAINTEXT)
av_push(types, newSVpv("userpass_plaintext", 0));
if (allow & GIT_CREDTYPE_SSH_KEY)
av_push(types, newSVpv("ssh_key", 0));
ENTER;
SAVETMPS;
PUSHMARK(SP);
mXPUSHs(newSVpv(url, 0));
mXPUSHs(newSVpv(usr_from_url, 0));
mXPUSHs(newRV_noinc((SV *)types));
PUTBACK;
call_sv(git_hv_code_entry((HV *)cbs, "credentials"), G_EVAL|G_SCALAR);
SPAGAIN;
if (SvTRUE(ERRSV)) {
rv = GIT_PASSTHROUGH;
(void) POPs;
} else {
SV *c = POPs;
if (SvOK(c)) {
creds = GIT_SV_TO_PTR(Cred, c);
if ((stash_opts->progress_payload = get_callback_option(hopt, "apply_progress")))
stash_opts->progress_cb = git_stash_apply_progress_cbb;
SAVEFREESV(MUTABLE_SV(stash_opts->progress_payload));
}
}
STATIC void git_hv_to_remote_callbacks(HV *opts, git_remote_callbacks *callbacks) {
callbacks->payload = (void *)opts;
if (get_callback_option(opts, "credentials"))
callbacks->credentials = git_credentials_cbb;
if (get_callback_option(opts, "certificate_check"))
callbacks->certificate_check = git_certificate_check_cbb;
if (get_callback_option(opts, "sideband_progress"))
callbacks->sideband_progress = git_sideband_progress_cbb;
if (get_callback_option(opts, "transfer_progress"))
callbacks->transfer_progress = git_transfer_progress_cbb;
deps/libgit2/deps/ntlmclient/ntlm.c view on Meta::CPAN
&ntlm->hostname_utf16,
&ntlm->hostname_utf16_len,
ntlm,
hostname,
strlen(hostname)))
return -1;
return 0;
}
static void free_credentials(ntlm_client *ntlm)
{
if (ntlm->password)
ntlm_memzero(ntlm->password, strlen(ntlm->password));
if (ntlm->password_utf16)
ntlm_memzero(ntlm->password_utf16, ntlm->password_utf16_len);
reset(ntlm->username);
reset(ntlm->username_upper);
reset(ntlm->userdomain);
deps/libgit2/deps/ntlmclient/ntlm.c view on Meta::CPAN
reset(ntlm->username_upper_utf16);
reset(ntlm->userdomain_utf16);
reset(ntlm->password_utf16);
ntlm->username_utf16_len = 0;
ntlm->username_upper_utf16_len = 0;
ntlm->userdomain_utf16_len = 0;
ntlm->password_utf16_len = 0;
}
int ntlm_client_set_credentials(
ntlm_client *ntlm,
const char *username,
const char *domain,
const char *password)
{
NTLM_ASSERT_ARG(ntlm);
ENSURE_INITIALIZED(ntlm);
free_credentials(ntlm);
if ((username && (ntlm->username = strdup(username)) == NULL) ||
(domain && (ntlm->userdomain = strdup(domain)) == NULL) ||
(password && (ntlm->password = strdup(password)) == NULL)) {
ntlm_client_set_errmsg(ntlm, "out of memory");
return -1;
}
if (username && supports_unicode(ntlm)) {
if ((ntlm->username_upper = strdup(username)) == NULL) {
deps/libgit2/deps/ntlmclient/ntlm.c view on Meta::CPAN
ntlm->state = NTLM_STATE_NEGOTIATE;
free_hostname(ntlm);
memset(&ntlm->host_version, 0, sizeof(ntlm_version));
reset(ntlm->target);
reset(ntlm->target_utf16);
ntlm->target_utf16_len = 0;
free_credentials(ntlm);
ntlm->nonce = 0;
ntlm->timestamp = 0;
memset(ntlm->lm_response, 0, NTLM_LM_RESPONSE_LEN);
ntlm->lm_response_len = 0;
memset(ntlm->ntlm_response, 0, NTLM_NTLM_RESPONSE_LEN);
ntlm->ntlm_response_len = 0;
deps/libgit2/deps/ntlmclient/ntlmclient.h view on Meta::CPAN
* domain should be in ASCII. These will not be sent to the remote host
* but will instead be used to compute the LM, NTLM or NTLM2 responses,
* which will be provided to the remote host during the response phase.
*
* @param ntlm the `ntlm_client` context to configure
* @param username the username to authenticate with
* @param domain the domain of the user authenticating
* @param password the password to authenticate with
* @return 0 on success, non-zero on failure
*/
NTLM_EXTERN(int) ntlm_client_set_credentials(
ntlm_client *ntlm,
const char *username,
const char *domain,
const char *password);
/**
* Sets the authentication target, your idea of the remote host's
* name. The target should be provided as ASCII. It will be
* provided to the remote host during the response phase.
*
deps/libgit2/deps/ntlmclient/ntlmclient.h view on Meta::CPAN
* @param message_len the length of the challenge message
* @return 0 on success, non-zero on failure
*/
NTLM_EXTERN(int) ntlm_client_set_challenge(
ntlm_client *ntlm,
const unsigned char *message,
size_t message_len);
/**
* Computes a response message (aka a "Type 3" message) to complete
* NTLM authentication with the server. The credentials should be
* set before calling this function. This message should be delivered
* to the server to complete authentication. This buffer should not
* be freed by the caller.
*
* @param out a pointer to the response message
* @param out_len a pointer to the length of the response message
* @param ntlm the `ntlm_client` context
* @return 0 on success, non-zero on failure
*/
NTLM_EXTERN(int) ntlm_client_response(
deps/libgit2/include/git2/clone.h view on Meta::CPAN
* These options are passed to the checkout step. To disable
* checkout, set the `checkout_strategy` to
* `GIT_CHECKOUT_NONE`.
*/
git_checkout_options checkout_opts;
/**
* Options which control the fetch, including callbacks.
*
* The callbacks are used for reporting fetch progress, and for acquiring
* credentials in the event they are needed.
*/
git_fetch_options fetch_opts;
/**
* Set to zero (false) to create a standard repo, or non-zero
* for a bare repo
*/
int bare;
/**
deps/libgit2/include/git2/credential.h view on Meta::CPAN
* (eg. SSH, with no username in its URL) does not know which username
* to use.
*
* @see git_credential_username_new
*/
GIT_CREDENTIAL_USERNAME = (1u << 5),
/**
* An SSH key-based authentication request
*
* Allows credentials to be read from memory instead of files.
* Note that because of differences in crypto backend support, it might
* not be functional.
*
* @see git_credential_ssh_key_memory_new
*/
GIT_CREDENTIAL_SSH_MEMORY = (1u << 6)
} git_credential_t;
/**
* The base structure for all credential types
*/
typedef struct git_credential git_credential;
typedef struct git_credential_userpass_plaintext git_credential_userpass_plaintext;
/** Username-only credential information */
typedef struct git_credential_username git_credential_username;
/** A key for NTLM/Kerberos "default" credentials */
typedef struct git_credential git_credential_default;
/**
* A ssh key from disk
*/
typedef struct git_credential_ssh_key git_credential_ssh_key;
/**
* Keyboard-interactive based ssh authentication
*/
deps/libgit2/include/git2/credential.h view on Meta::CPAN
* Credential acquisition callback.
*
* This callback is usually involved any time another system might need
* authentication. As such, you are expected to provide a valid
* git_credential object back, depending on allowed_types (a
* git_credential_t bitmask).
*
* Note that most authentication details are your responsibility - this
* callback will be called until the authentication succeeds, or you report
* an error. As such, it's easy to get in a loop if you fail to stop providing
* the same incorrect credentials.
*
* @param out The newly created credential object.
* @param url The resource for which we are demanding a credential.
* @param username_from_url The username that was embedded in a "user\@host"
* remote url, or NULL if not included.
* @param allowed_types A bitmask stating which credential types are OK to return.
* @param payload The payload provided when specifying this callback.
* @return 0 for success, < 0 to indicate an error, > 0 to indicate
* no credential was acquired
*/
deps/libgit2/include/git2/proxy.h view on Meta::CPAN
*/
const char *url;
/**
* This will be called if the remote host requires
* authentication in order to connect to it.
*
* Returning GIT_PASSTHROUGH will make libgit2 behave as
* though this field isn't set.
*/
git_credential_acquire_cb credentials;
/**
* If cert verification fails, this will be called to let the
* user make the final decision of whether to allow the
* connection to proceed. Returns 0 to allow the connection
* or a negative value to indicate an error.
*/
git_transport_certificate_check_cb certificate_check;
/**
* Payload to be provided to the credentials and certificate
* check callbacks.
*/
void *payload;
} git_proxy_options;
#define GIT_PROXY_OPTIONS_VERSION 1
#define GIT_PROXY_OPTIONS_INIT {GIT_PROXY_OPTIONS_VERSION}
/**
* Initialize git_proxy_options structure
deps/libgit2/include/git2/remote.h view on Meta::CPAN
*/
int GIT_CALLBACK(completion)(git_remote_completion_t type, void *data);
/**
* This will be called if the remote host requires
* authentication in order to connect to it.
*
* Returning GIT_PASSTHROUGH will make libgit2 behave as
* though this field isn't set.
*/
git_credential_acquire_cb credentials;
/**
* If cert verification fails, this will be called to let the
* user make the final decision of whether to allow the
* connection to proceed. Returns 0 to allow the connection
* or a negative value to indicate an error.
*/
git_transport_certificate_check_cb certificate_check;
/**
deps/libgit2/include/git2/submodule.h view on Meta::CPAN
* `GIT_CHECKOUT_NONE`. Generally you will want the use
* GIT_CHECKOUT_SAFE to update files in the working
* directory.
*/
git_checkout_options checkout_opts;
/**
* Options which control the fetch, including callbacks.
*
* The callbacks to use for reporting fetch progress, and for acquiring
* credentials in the event they are needed.
*/
git_fetch_options fetch_opts;
/**
* Allow fetching from the submodule's default remote if the target
* commit isn't found. Enabled by default.
*/
int allow_fetch;
} git_submodule_update_options;
deps/libgit2/include/git2/sys/credential.h view on Meta::CPAN
* a Linking Exception. For full terms see the included COPYING file.
*/
#ifndef INCLUDE_sys_git_credential_h__
#define INCLUDE_sys_git_credential_h__
#include "git2/common.h"
#include "git2/credential.h"
/**
* @file git2/sys/cred.h
* @brief Git credentials low-level implementation
* @defgroup git_credential Git credentials low-level implementation
* @ingroup Git
* @{
*/
GIT_BEGIN_DECL
/**
* The base structure for all credential types
*/
struct git_credential {
git_credential_t credtype; /**< A type of credential */
/** The deallocator for this type of credentials */
void GIT_CALLBACK(free)(git_credential *cred);
};
/** A plaintext username and password */
struct git_credential_userpass_plaintext {
git_credential parent; /**< The parent credential */
char *username; /**< The username to authenticate as */
char *password; /**< The password to use */
};
deps/libgit2/include/git2/sys/transport.h view on Meta::CPAN
* @param valid whether we believe the certificate is valid
* @param hostname the hostname we connected to
* @return the return value of the callback: 0 for no error, GIT_PASSTHROUGH
* to indicate that there is no callback registered (or the callback
* refused to validate the certificate and callers should behave as
* if no callback was set), or < 0 for an error
*/
GIT_EXTERN(int) git_transport_smart_certificate_check(git_transport *transport, git_cert *cert, int valid, const char *hostname);
/**
* Call the credentials callback for this transport
*
* @param out the pointer where the creds are to be stored
* @param transport a smart transport
* @param user the user we saw on the url (if any)
* @param methods available methods for authentication
* @return the return value of the callback: 0 for no error, GIT_PASSTHROUGH
* to indicate that there is no callback registered (or the callback
* refused to provide credentials and callers should behave as if no
* callback was set), or < 0 for an error
*/
GIT_EXTERN(int) git_transport_smart_credentials(git_credential **out, git_transport *transport, const char *user, int methods);
/**
* Get a copy of the remote connect options
*
* All data is copied and must be freed by the caller by calling
* `git_remote_connect_options_dispose`.
*
* @param out options struct to fill
* @param transport the transport to extract the data from.
*/
deps/libgit2/src/libgit2/transports/auth.h view on Meta::CPAN
GIT_HTTP_AUTH_NEGOTIATE = 2,
GIT_HTTP_AUTH_NTLM = 4
} git_http_auth_t;
typedef struct git_http_auth_context git_http_auth_context;
struct git_http_auth_context {
/** Type of scheme */
git_http_auth_t type;
/** Supported credentials */
git_credential_t credtypes;
/** Connection affinity or request affinity */
unsigned connection_affinity : 1;
/** Sets the challenge on the authentication context */
int (*set_challenge)(git_http_auth_context *ctx, const char *challenge);
/** Gets the next authentication token from the context */
int (*next_token)(git_str *out, git_http_auth_context *ctx, git_credential *cred);
deps/libgit2/src/libgit2/transports/auth_ntlm.c view on Meta::CPAN
GIT_ASSERT_ARG(challenge);
git__free(ctx->challenge);
ctx->challenge = git__strdup(challenge);
GIT_ERROR_CHECK_ALLOC(ctx->challenge);
return 0;
}
static int ntlm_set_credentials(http_auth_ntlm_context *ctx, git_credential *_cred)
{
git_credential_userpass_plaintext *cred;
const char *sep, *username;
char *domain = NULL, *domainuser = NULL;
int error = 0;
GIT_ASSERT(_cred->credtype == GIT_CREDENTIAL_USERPASS_PLAINTEXT);
cred = (git_credential_userpass_plaintext *)_cred;
if ((sep = strchr(cred->username, '\\')) != NULL) {
deps/libgit2/src/libgit2/transports/auth_ntlm.c view on Meta::CPAN
GIT_ERROR_CHECK_ALLOC(domain);
domainuser = git__strdup(sep + 1);
GIT_ERROR_CHECK_ALLOC(domainuser);
username = domainuser;
} else {
username = cred->username;
}
if (ntlm_client_set_credentials(ctx->ntlm,
username, domain, cred->password) < 0) {
git_error_set(GIT_ERROR_NET, "could not set credentials: %s",
ntlm_client_errmsg(ctx->ntlm));
error = -1;
goto done;
}
done:
git__free(domain);
git__free(domainuser);
return error;
}
deps/libgit2/src/libgit2/transports/auth_ntlm.c view on Meta::CPAN
if (ctx->complete)
ntlm_client_reset(ctx->ntlm);
/*
* Set us complete now since it's the default case; the one
* incomplete case (successfully created a client request)
* will explicitly set that it requires a second step.
*/
ctx->complete = true;
if (cred && ntlm_set_credentials(ctx, cred) != 0)
goto done;
if (challenge_len < 4) {
git_error_set(GIT_ERROR_NET, "no ntlm challenge sent from server");
goto done;
} else if (challenge_len == 4) {
if (memcmp(ctx->challenge, "NTLM", 4) != 0) {
git_error_set(GIT_ERROR_NET, "server did not request NTLM");
goto done;
}
deps/libgit2/src/libgit2/transports/credential.c view on Meta::CPAN
passphrase,
GIT_CREDENTIAL_SSH_MEMORY);
#else
GIT_UNUSED(cred);
GIT_UNUSED(username);
GIT_UNUSED(publickey);
GIT_UNUSED(privatekey);
GIT_UNUSED(passphrase);
git_error_set(GIT_ERROR_INVALID,
"this version of libgit2 was not built with ssh memory credentials.");
return -1;
#endif
}
static int git_credential_ssh_key_type_new(
git_credential **cred,
const char *username,
const char *publickey,
const char *privatekey,
const char *passphrase,
deps/libgit2/src/libgit2/transports/credential_helpers.c view on Meta::CPAN
void *payload)
{
git_credential_userpass_payload *userpass = (git_credential_userpass_payload*)payload;
const char *effective_username = NULL;
GIT_UNUSED(url);
if (!userpass || !userpass->password) return -1;
/* Username resolution: a username can be passed with the URL, the
* credentials payload, or both. Here's what we do. Note that if we get
* this far, we know that any password the url may contain has already
* failed at least once, so we ignore it.
*
* | Payload | URL | Used |
* +-------------+----------+-----------+
* | yes | no | payload |
* | yes | yes | payload |
* | no | yes | url |
* | no | no | FAIL |
*/
deps/libgit2/src/libgit2/transports/http.c view on Meta::CPAN
"application/x-git-receive-pack-result",
0,
1
};
#define SERVER_TYPE_REMOTE "remote"
#define SERVER_TYPE_PROXY "proxy"
#define OWNING_SUBTRANSPORT(s) ((http_subtransport *)(s)->parent.subtransport)
static int apply_url_credentials(
git_credential **cred,
unsigned int allowed_types,
const char *username,
const char *password)
{
GIT_ASSERT_ARG(username);
if (!password)
password = "";
deps/libgit2/src/libgit2/transports/http.c view on Meta::CPAN
unsigned int allowed_schemetypes,
unsigned int allowed_credtypes,
git_credential_acquire_cb callback,
void *callback_payload)
{
int error = 1;
if (server->cred)
free_cred(&server->cred);
/* Start with URL-specified credentials, if there were any. */
if ((allowed_credtypes & GIT_CREDENTIAL_USERPASS_PLAINTEXT) &&
!server->url_cred_presented &&
server->url.username) {
error = apply_url_credentials(&server->cred, allowed_credtypes, server->url.username, server->url.password);
server->url_cred_presented = 1;
/* treat GIT_PASSTHROUGH as if callback isn't set */
if (error == GIT_PASSTHROUGH)
error = 1;
}
if (error > 0 && callback) {
error = callback(&server->cred, url, server->url.username, allowed_credtypes, callback_payload);
deps/libgit2/src/libgit2/transports/http.c view on Meta::CPAN
git_http_response *response)
{
http_subtransport *transport = OWNING_SUBTRANSPORT(stream);
git_remote_connect_options *connect_opts = &transport->owner->connect_opts;
if (response->server_auth_credtypes == 0) {
git_error_set(GIT_ERROR_HTTP, "server requires authentication that we do not support");
return GIT_EAUTH;
}
/* Otherwise, prompt for credentials. */
return handle_auth(
&transport->server,
SERVER_TYPE_REMOTE,
transport->owner->url,
response->server_auth_schemetypes,
response->server_auth_credtypes,
connect_opts->callbacks.credentials,
connect_opts->callbacks.payload);
}
GIT_INLINE(int) handle_proxy_auth(
http_stream *stream,
git_http_response *response)
{
http_subtransport *transport = OWNING_SUBTRANSPORT(stream);
git_remote_connect_options *connect_opts = &transport->owner->connect_opts;
if (response->proxy_auth_credtypes == 0) {
git_error_set(GIT_ERROR_HTTP, "proxy requires authentication that we do not support");
return GIT_EAUTH;
}
/* Otherwise, prompt for credentials. */
return handle_auth(
&transport->proxy,
SERVER_TYPE_PROXY,
connect_opts->proxy_opts.url,
response->server_auth_schemetypes,
response->proxy_auth_credtypes,
connect_opts->proxy_opts.credentials,
connect_opts->proxy_opts.payload);
}
static bool allow_redirect(http_stream *stream)
{
http_subtransport *transport = OWNING_SUBTRANSPORT(stream);
switch (transport->owner->connect_opts.follow_redirects) {
case GIT_REMOTE_REDIRECT_INITIAL:
return (stream->service->initial == 1);
deps/libgit2/src/libgit2/transports/http.c view on Meta::CPAN
return -1;
}
return 0;
} else if (git_http_response_is_redirect(response)) {
git_error_set(GIT_ERROR_HTTP, "unexpected redirect");
return -1;
}
/* If we're in the middle of challenge/response auth, continue. */
if (allow_replay && response->resend_credentials) {
return 0;
} else if (allow_replay && response->status == GIT_HTTP_STATUS_UNAUTHORIZED) {
if ((error = handle_remote_auth(stream, response)) < 0)
return error;
return git_http_client_skip_body(transport->http_client);
} else if (allow_replay && response->status == GIT_HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED) {
if ((error = handle_proxy_auth(stream, response)) < 0)
return error;
deps/libgit2/src/libgit2/transports/http.c view on Meta::CPAN
bool use_proxy = false;
int error;
if ((error = git_net_url_joinpath(url,
&transport->server.url, stream->service->url)) < 0 ||
(error = lookup_proxy(&use_proxy, transport)) < 0)
return error;
request->method = stream->service->method;
request->url = url;
request->credentials = transport->server.cred;
request->proxy = use_proxy ? &transport->proxy.url : NULL;
request->proxy_credentials = transport->proxy.cred;
request->custom_headers = &transport->owner->connect_opts.custom_headers;
if (stream->service->method == GIT_HTTP_METHOD_POST) {
request->chunked = stream->service->chunked;
request->content_length = stream->service->chunked ? 0 : len;
request->content_type = stream->service->request_type;
request->accept = stream->service->response_type;
request->expect_continue = git_http__expect_continue;
}
deps/libgit2/src/libgit2/transports/httpclient.c view on Meta::CPAN
ctx->client->keepalive = http_should_keep_alive(parser);
/* Prepare for authentication */
collect_authinfo(&ctx->response->server_auth_schemetypes,
&ctx->response->server_auth_credtypes,
&ctx->client->server.auth_challenges);
collect_authinfo(&ctx->response->proxy_auth_schemetypes,
&ctx->response->proxy_auth_credtypes,
&ctx->client->proxy.auth_challenges);
ctx->response->resend_credentials = resend_needed(ctx->client,
ctx->response);
/* Stop parsing. */
http_parser_pause(parser, 1);
if (ctx->response->content_type || ctx->response->chunked)
ctx->client->state = READING_BODY;
else
ctx->client->state = DONE;
deps/libgit2/src/libgit2/transports/httpclient.c view on Meta::CPAN
case GIT_HTTP_METHOD_POST:
return "POST";
case GIT_HTTP_METHOD_CONNECT:
return "CONNECT";
}
return NULL;
}
/*
* Find the scheme that is suitable for the given credentials, based on the
* server's auth challenges.
*/
static bool best_scheme_and_challenge(
git_http_auth_scheme **scheme_out,
const char **challenge_out,
git_vector *challenges,
git_credential *credentials)
{
const char *challenge;
size_t i, j;
for (i = 0; i < ARRAY_SIZE(auth_schemes); i++) {
git_vector_foreach(challenges, j, challenge) {
git_http_auth_scheme *scheme = &auth_schemes[i];
if (challenge_matches_scheme(challenge, scheme) &&
(scheme->credtypes & credentials->credtype)) {
*scheme_out = scheme;
*challenge_out = challenge;
return true;
}
}
}
return false;
}
deps/libgit2/src/libgit2/transports/httpclient.c view on Meta::CPAN
}
}
}
return NULL;
}
static const char *init_auth_context(
git_http_server *server,
git_vector *challenges,
git_credential *credentials)
{
git_http_auth_scheme *scheme;
const char *challenge;
int error;
if (!best_scheme_and_challenge(&scheme, &challenge, challenges, credentials)) {
git_error_set(GIT_ERROR_HTTP, "could not find appropriate mechanism for credentials");
return NULL;
}
error = scheme->init_context(&server->auth_context, &server->url);
if (error == GIT_PASSTHROUGH) {
git_error_set(GIT_ERROR_HTTP, "'%s' authentication is not supported", scheme->name);
return NULL;
}
deps/libgit2/src/libgit2/transports/httpclient.c view on Meta::CPAN
{
if (!server->auth_context)
return;
if (server->auth_context->free)
server->auth_context->free(server->auth_context);
server->auth_context = NULL;
}
static int apply_credentials(
git_str *buf,
git_http_server *server,
const char *header_name,
git_credential *credentials)
{
git_http_auth_context *auth = server->auth_context;
git_vector *challenges = &server->auth_challenges;
const char *challenge;
git_str token = GIT_STR_INIT;
int error = 0;
/* We've started a new request without creds; free the context. */
if (auth && !credentials) {
free_auth_context(server);
return 0;
}
/* We haven't authenticated, nor were we asked to. Nothing to do. */
if (!auth && !git_vector_length(challenges))
return 0;
if (!auth) {
challenge = init_auth_context(server, challenges, credentials);
auth = server->auth_context;
if (!challenge || !auth) {
error = -1;
goto done;
}
} else if (auth->set_challenge) {
challenge = challenge_for_context(challenges, auth);
}
if (auth->set_challenge && challenge &&
(error = auth->set_challenge(auth, challenge)) < 0)
goto done;
if ((error = auth->next_token(&token, auth, credentials)) < 0)
goto done;
if (auth->is_complete && auth->is_complete(auth)) {
/*
* If we're done with an auth mechanism with connection affinity,
* we don't need to send any more headers and can dispose the context.
*/
if (auth->connection_affinity)
free_auth_context(server);
} else if (!token.size) {
deps/libgit2/src/libgit2/transports/httpclient.c view on Meta::CPAN
}
if (token.size > 0)
error = git_str_printf(buf, "%s: %s\r\n", header_name, token.ptr);
done:
git_str_dispose(&token);
return error;
}
GIT_INLINE(int) apply_server_credentials(
git_str *buf,
git_http_client *client,
git_http_request *request)
{
return apply_credentials(buf,
&client->server,
"Authorization",
request->credentials);
}
GIT_INLINE(int) apply_proxy_credentials(
git_str *buf,
git_http_client *client,
git_http_request *request)
{
return apply_credentials(buf,
&client->proxy,
"Proxy-Authorization",
request->proxy_credentials);
}
static int puts_host_and_port(git_str *buf, git_net_url *url, bool force_port)
{
bool ipv6 = git_net_url_is_ipv6(url);
if (ipv6)
git_str_putc(buf, '[');
git_str_puts(buf, url->host);
deps/libgit2/src/libgit2/transports/httpclient.c view on Meta::CPAN
git_str_puts(buf, " HTTP/1.1\r\n");
git_str_puts(buf, "User-Agent: ");
git_http__user_agent(buf);
git_str_puts(buf, "\r\n");
git_str_puts(buf, "Host: ");
puts_host_and_port(buf, &client->server.url, true);
git_str_puts(buf, "\r\n");
if ((error = apply_proxy_credentials(buf, client, request) < 0))
return -1;
git_str_puts(buf, "\r\n");
return git_str_oom(buf) ? -1 : 0;
}
static bool use_connect_proxy(git_http_client *client)
{
return client->proxy.url.host && !strcmp(client->server.url.scheme, "https");
deps/libgit2/src/libgit2/transports/httpclient.c view on Meta::CPAN
if (request->chunked)
git_str_puts(buf, "Transfer-Encoding: chunked\r\n");
if (request->content_length > 0)
git_str_printf(buf, "Content-Length: %"PRIuZ "\r\n",
request->content_length);
if (request->expect_continue)
git_str_printf(buf, "Expect: 100-continue\r\n");
if ((error = apply_server_credentials(buf, client, request)) < 0 ||
(!use_connect_proxy(client) &&
(error = apply_proxy_credentials(buf, client, request)) < 0))
return error;
if (request->custom_headers) {
for (i = 0; i < request->custom_headers->count; i++) {
const char *hdr = request->custom_headers->strings[i];
if (hdr)
git_str_printf(buf, "%s\r\n", hdr);
}
}
deps/libgit2/src/libgit2/transports/httpclient.h view on Meta::CPAN
/** An HTTP request */
typedef struct {
git_http_method method; /**< Method for the request */
git_net_url *url; /**< Full request URL */
git_net_url *proxy; /**< Proxy to use */
/* Headers */
const char *accept; /**< Contents of the Accept header */
const char *content_type; /**< Content-Type header (for POST) */
git_credential *credentials; /**< Credentials to authenticate with */
git_credential *proxy_credentials; /**< Credentials for proxy */
git_strarray *custom_headers; /**< Additional headers to deliver */
/* To POST a payload, either set content_length OR set chunked. */
size_t content_length; /**< Length of the POST body */
unsigned chunked : 1, /**< Post with chunking */
expect_continue : 1; /**< Use expect/continue negotiation */
} git_http_request;
typedef struct {
int status;
deps/libgit2/src/libgit2/transports/httpclient.h view on Meta::CPAN
char *location;
/* Authentication headers */
unsigned server_auth_schemetypes; /**< Schemes requested by remote */
unsigned server_auth_credtypes; /**< Supported cred types for remote */
unsigned proxy_auth_schemetypes; /**< Schemes requested by proxy */
unsigned proxy_auth_credtypes; /**< Supported cred types for proxy */
unsigned chunked : 1, /**< Response body is chunked */
resend_credentials : 1; /**< Resend with authentication */
} git_http_response;
typedef struct {
/** Certificate check callback for the remote */
git_transport_certificate_check_cb server_certificate_check_cb;
void *server_certificate_check_payload;
/** Certificate check callback for the proxy */
git_transport_certificate_check_cb proxy_certificate_check_cb;
void *proxy_certificate_check_payload;
deps/libgit2/src/libgit2/transports/smart.c view on Meta::CPAN
GIT_ASSERT_ARG(transport);
GIT_ASSERT_ARG(cert);
GIT_ASSERT_ARG(hostname);
if (!connect_opts->callbacks.certificate_check)
return GIT_PASSTHROUGH;
return connect_opts->callbacks.certificate_check(cert, valid, hostname, connect_opts->callbacks.payload);
}
int git_transport_smart_credentials(git_credential **out, git_transport *transport, const char *user, int methods)
{
transport_smart *t = GIT_CONTAINER_OF(transport, transport_smart, parent);
git_remote_connect_options *connect_opts = &t->connect_opts;
GIT_ASSERT_ARG(out);
GIT_ASSERT_ARG(transport);
if (!connect_opts->callbacks.credentials)
return GIT_PASSTHROUGH;
return connect_opts->callbacks.credentials(out, t->url, user, methods, connect_opts->callbacks.payload);
}
int git_transport_remote_connect_options(
git_remote_connect_options *out,
git_transport *transport)
{
transport_smart *t = GIT_CONTAINER_OF(transport, transport_smart, parent);
GIT_ASSERT_ARG(out);
GIT_ASSERT_ARG(transport);
deps/libgit2/src/libgit2/transports/ssh.c view on Meta::CPAN
}
return 0;
}
static int request_creds(git_credential **out, ssh_subtransport *t, const char *user, int auth_methods)
{
int error, no_callback = 0;
git_credential *cred = NULL;
if (!t->owner->connect_opts.callbacks.credentials) {
no_callback = 1;
} else {
error = t->owner->connect_opts.callbacks.credentials(
&cred,
t->owner->url,
user,
auth_methods,
t->owner->connect_opts.callbacks.payload);
if (error == GIT_PASSTHROUGH) {
no_callback = 1;
} else if (error < 0) {
return error;
} else if (!cred) {
git_error_set(GIT_ERROR_SSH, "callback failed to initialize SSH credentials");
return -1;
}
}
if (no_callback) {
git_error_set(GIT_ERROR_SSH, "authentication required but no callback set");
return GIT_EAUTH;
}
if (!(cred->credtype & auth_methods)) {
cred->free(cred);
git_error_set(GIT_ERROR_SSH, "authentication callback returned unsupported credentials type");
return GIT_EAUTH;
}
*out = cred;
return 0;
}
static int _git_ssh_session_create(
LIBSSH2_SESSION **session,
deps/libgit2/src/libgit2/transports/winhttp.c view on Meta::CPAN
git_smart_subtransport parent;
transport_smart *owner;
winhttp_server server;
winhttp_server proxy;
HINTERNET session;
HINTERNET connection;
} winhttp_subtransport;
static int apply_userpass_credentials(HINTERNET request, DWORD target, int mechanisms, git_credential *cred)
{
git_credential_userpass_plaintext *c = (git_credential_userpass_plaintext *)cred;
wchar_t *user = NULL, *pass = NULL;
int user_len = 0, pass_len = 0, error = 0;
DWORD native_scheme;
if (mechanisms & GIT_WINHTTP_AUTH_NEGOTIATE) {
native_scheme = WINHTTP_AUTH_SCHEME_NEGOTIATE;
} else if (mechanisms & GIT_WINHTTP_AUTH_NTLM) {
native_scheme = WINHTTP_AUTH_SCHEME_NTLM;
deps/libgit2/src/libgit2/transports/winhttp.c view on Meta::CPAN
goto done;
}
if ((error = user_len = git__utf8_to_16_alloc(&user, c->username)) < 0)
goto done;
if ((error = pass_len = git__utf8_to_16_alloc(&pass, c->password)) < 0)
goto done;
if (!WinHttpSetCredentials(request, target, native_scheme, user, pass, NULL)) {
git_error_set(GIT_ERROR_OS, "failed to set credentials");
error = -1;
}
done:
if (user_len > 0)
git__memzero(user, user_len * sizeof(wchar_t));
if (pass_len > 0)
git__memzero(pass, pass_len * sizeof(wchar_t));
git__free(user);
git__free(pass);
return error;
}
static int apply_default_credentials(HINTERNET request, DWORD target, int mechanisms)
{
DWORD autologon_level = WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW;
DWORD native_scheme = 0;
if ((mechanisms & GIT_WINHTTP_AUTH_NEGOTIATE) != 0) {
native_scheme = WINHTTP_AUTH_SCHEME_NEGOTIATE;
} else if ((mechanisms & GIT_WINHTTP_AUTH_NTLM) != 0) {
native_scheme = WINHTTP_AUTH_SCHEME_NTLM;
} else {
git_error_set(GIT_ERROR_HTTP, "invalid authentication scheme");
deps/libgit2/src/libgit2/transports/winhttp.c view on Meta::CPAN
/*
* Autologon policy must be "low" to use default creds.
* This is safe as the user has explicitly requested it.
*/
if (!WinHttpSetOption(request, WINHTTP_OPTION_AUTOLOGON_POLICY, &autologon_level, sizeof(DWORD))) {
git_error_set(GIT_ERROR_OS, "could not configure logon policy");
return -1;
}
if (!WinHttpSetCredentials(request, target, native_scheme, NULL, NULL, NULL)) {
git_error_set(GIT_ERROR_OS, "could not configure credentials");
return -1;
}
return 0;
}
static int acquire_url_cred(
git_credential **cred,
unsigned int allowed_types,
const char *username,
deps/libgit2/src/libgit2/transports/winhttp.c view on Meta::CPAN
if (SUCCEEDED(pISM->lpVtbl->MapUrlToZone(pISM, wide_url, &dwZone, 0)) &&
(URLZONE_LOCAL_MACHINE == dwZone ||
URLZONE_INTRANET == dwZone ||
URLZONE_TRUSTED == dwZone)) {
git_credential *existing = *cred;
if (existing)
existing->free(existing);
/* Then use default Windows credentials to authenticate this request */
error = git_credential_default_new(cred);
}
pISM->lpVtbl->Release(pISM);
}
/* Only uninitialize if the call to CoInitializeEx was successful. */
if (SUCCEEDED(hCoInitResult))
CoUninitialize();
}
deps/libgit2/src/libgit2/transports/winhttp.c view on Meta::CPAN
}
if (s->request) {
WinHttpCloseHandle(s->request);
s->request = NULL;
}
s->sent_request = 0;
}
static int apply_credentials(
HINTERNET request,
git_net_url *url,
int target,
git_credential *creds,
int mechanisms)
{
int error = 0;
GIT_UNUSED(url);
/* If we have creds, just apply them */
if (creds && creds->credtype == GIT_CREDENTIAL_USERPASS_PLAINTEXT)
error = apply_userpass_credentials(request, target, mechanisms, creds);
else if (creds && creds->credtype == GIT_CREDENTIAL_DEFAULT)
error = apply_default_credentials(request, target, mechanisms);
return error;
}
static int winhttp_stream_connect(winhttp_stream *s)
{
winhttp_subtransport *t = OWNING_SUBTRANSPORT(s);
git_str buf = GIT_STR_INIT;
char *proxy_url = NULL;
wchar_t ct[MAX_CONTENT_TYPE_LEN];
deps/libgit2/src/libgit2/transports/winhttp.c view on Meta::CPAN
NULL,
WINHTTP_NO_REFERER,
types,
git__strcmp(t->server.url.scheme, "https") == 0 ? WINHTTP_FLAG_SECURE : 0);
if (!s->request) {
git_error_set(GIT_ERROR_OS, "failed to open request");
goto on_error;
}
/* Never attempt default credentials; we'll provide them explicitly. */
if (!WinHttpSetOption(s->request, WINHTTP_OPTION_AUTOLOGON_POLICY, &autologon_policy, sizeof(DWORD)))
return -1;
if (!WinHttpSetTimeouts(s->request, default_timeout, default_connect_timeout, default_timeout, default_timeout)) {
git_error_set(GIT_ERROR_OS, "failed to set timeouts for WinHTTP");
goto on_error;
}
proxy_opts = &t->owner->connect_opts.proxy_opts;
if (proxy_opts->type == GIT_PROXY_AUTO) {
deps/libgit2/src/libgit2/transports/winhttp.c view on Meta::CPAN
WINHTTP_OPTION_PROXY,
&proxy_info,
sizeof(WINHTTP_PROXY_INFO))) {
git_error_set(GIT_ERROR_OS, "failed to set proxy");
git__free(proxy_wide);
goto on_error;
}
git__free(proxy_wide);
if ((error = apply_credentials(s->request, &t->proxy.url, WINHTTP_AUTH_TARGET_PROXY, t->proxy.cred, t->proxy.auth_mechanisms)) < 0)
goto on_error;
}
/* Disable WinHTTP redirects so we can handle them manually. Why, you ask?
* http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/b2ff8879-ab9f-4218-8f09-16d25dff87ae
*/
if (!WinHttpSetOption(s->request,
WINHTTP_OPTION_DISABLE_FEATURE,
&disable_redirects,
sizeof(disable_redirects))) {
deps/libgit2/src/libgit2/transports/winhttp.c view on Meta::CPAN
}
if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L,
WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) {
git_error_set(GIT_ERROR_OS, "failed to add a header to the request");
goto on_error;
}
}
}
if ((error = apply_credentials(s->request, &t->server.url, WINHTTP_AUTH_TARGET_SERVER, t->server.cred, t->server.auth_mechanisms)) < 0)
goto on_error;
/* We've done everything up to calling WinHttpSendRequest. */
error = 0;
on_error:
if (error < 0)
winhttp_stream_close(s);
deps/libgit2/src/libgit2/transports/winhttp.c view on Meta::CPAN
if (!WinHttpSetOption(s->request, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, WINHTTP_NO_CLIENT_CERT_CONTEXT, 0)) {
git_error_set(GIT_ERROR_OS, "failed to set client cert context");
return -1;
}
}
}
return error;
}
static int acquire_credentials(
HINTERNET request,
winhttp_server *server,
const char *url_str,
git_credential_acquire_cb cred_cb,
void *cred_cb_payload)
{
int allowed_types;
int error = 1;
if (parse_unauthorized_response(&allowed_types, &server->auth_mechanisms, request) < 0)
return -1;
if (allowed_types) {
git_credential_free(server->cred);
server->cred = NULL;
/* Start with URL-specified credentials, if there were any. */
if (!server->url_cred_presented && server->url.username && server->url.password) {
error = acquire_url_cred(&server->cred, allowed_types, server->url.username, server->url.password);
server->url_cred_presented = 1;
if (error < 0)
return error;
}
/* Next use the user-defined callback, if there is one. */
if (error > 0 && cred_cb) {
deps/libgit2/src/libgit2/transports/winhttp.c view on Meta::CPAN
/* Finally, invoke the fallback default credential lookup. */
if (error > 0) {
error = acquire_fallback_cred(&server->cred, url_str, allowed_types);
if (error < 0)
return error;
}
}
/*
* No error occurred but we could not find appropriate credentials.
* This behaves like a pass-through.
*/
return error;
}
static int winhttp_stream_read(
git_smart_subtransport_stream *stream,
char *buffer,
size_t buf_size,
size_t *bytes_read)
deps/libgit2/src/libgit2/transports/winhttp.c view on Meta::CPAN
if (winhttp_connect(t) < 0)
return -1;
}
git__free(location8);
goto replay;
}
/* Handle authentication failures */
if (status_code == HTTP_STATUS_DENIED) {
int error = acquire_credentials(s->request,
&t->server,
t->owner->url,
t->owner->connect_opts.callbacks.credentials,
t->owner->connect_opts.callbacks.payload);
if (error < 0) {
return error;
} else if (!error) {
GIT_ASSERT(t->server.cred);
winhttp_stream_close(s);
goto replay;
}
} else if (status_code == HTTP_STATUS_PROXY_AUTH_REQ) {
int error = acquire_credentials(s->request,
&t->proxy,
t->owner->connect_opts.proxy_opts.url,
t->owner->connect_opts.proxy_opts.credentials,
t->owner->connect_opts.proxy_opts.payload);
if (error < 0) {
return error;
} else if (!error) {
GIT_ASSERT(t->proxy.cred);
winhttp_stream_close(s);
goto replay;
}
}
lib/Git/Raw/Cred.pm view on Meta::CPAN
package Git::Raw::Cred;
$Git::Raw::Cred::VERSION = '0.90';
use strict;
use warnings;
=head1 NAME
Git::Raw::Cred - Git credentials class
=head1 VERSION
version 0.90
=head1 DESCRIPTION
A L<Git::Raw::Cred> object is used to store credentials.
B<WARNING>: The API of this module is unstable and may change without warning
(any change will be appropriately documented in the changelog).
=head1 METHODS
=head2 userpass( $user, $pass )
Create a new credential object with the given username and password.
lib/Git/Raw/Remote.pm view on Meta::CPAN
=head1 SYNOPSIS
use Git::Raw;
# open the Git repository at $path
my $repo = Git::Raw::Repository -> open($path);
# add a new remote
my $remote = Git::Raw::Remote -> create($repo, 'origin', $url);
# connect the remote and set the acquire credentials callback
$remote -> connect('fetch', {
'credentials' => sub {
Git::Raw::Cred -> userpass($usr, $pwd)
},
});
# fetch from the remote and update the local tips
$remote -> download;
$remote -> update_tips({
'update_tips' => sub {
my ($ref, $a, $b) = @_;
print "Updated $ref: $a -> $b", "\n";
lib/Git/Raw/Remote.pm view on Meta::CPAN
=head2 update_tips( [ \%callbacks ] )
Update the tips to the new status.
=head2 is_connected( )
Check if the remote is connected.
=head1 CALLBACKS
=head2 credentials
The callback to be called any time authentication is required to connect to the
remote repository. The callback receives a string C<$url> containing the URL of
the remote, the C<$user> extracted from the URL and a list of supported
authentication C<$types>. The callback should return either a L<Git::Raw::Cred>
object or alternatively C<undef> to abort the authentication process. C<$types>
may contain one or more of the following:
=over 4
lib/Git/Raw/Remote.pm view on Meta::CPAN
=item * "ssh_interactive"
Keyboard-interactive based SSH authentication
=item * "username"
Username-only credential information.
=item * "default"
A key for NTLM/Kerberos default credentials.
=back
B<Note:> this callback may be invoked more than once.
=head2 certificate_check
Callback to be invoked if cert verification fails. The callback receives a
L<Git::Raw::Cert::X509> or L<Git::Raw::Cert::HostKey> object, a truthy
value C<$valid> and C<$host>. This callback should return a negative number to
t/10-clone.t view on Meta::CPAN
my %features = Git::Raw -> features;
if ($features{'https'} == 0) {
diag("HTTPS support not available, skipping HTTPS clone tests");
done_testing;
exit;
}
$url = 'https://github.com/libgit2/TestGitRepository.git';
$path = rel2abs(catfile('t', 'test_repo_clone'));
my ($credentials_fired, $certificate_check_fired, $update_tips_fired) = (0, 0, 0);
$repo = Git::Raw::Repository -> clone($url, $path, {}, {
'callbacks' => {
'certificate_check' => sub {
my ($cert, $valid, $host) = @_;
$certificate_check_fired = 1;
isa_ok $cert, 'Git::Raw::Cert';
isa_ok $cert, 'Git::Raw::Cert::X509';
is $cert -> type, 'x509';
t/10-clone.t view on Meta::CPAN
like $ref, qr/refs/;
ok !defined($a);
ok defined($b);
}
}
});
ok !$repo -> is_empty;
is $credentials_fired, 0;
is $certificate_check_fired, 1;
is $update_tips_fired, 1;
$repo = undef;
rmtree catfile('t', 'test_repo_clone');
if ($^O eq 'MSWin32') {
diag("Windows doesn't have a SSH server, skipping SSH clone tests");
t/10-clone.t view on Meta::CPAN
}
my $remote_path = rel2abs(catfile('t', 'test_repo'));
my $remote_port = $ENV{AUTHOR_TESTING} ? 22 : 2222;
my $remote_url = "ssh://$ENV{USER}\@localhost:$remote_port$remote_path";
$path = rel2abs(catfile('t', 'test_repo_ssh'));
# Not a CV for callback
ok (!eval { $repo = Git::Raw::Repository -> clone($remote_url, $path, {}, {
'callbacks' => {
'credentials' => 'blah'
}
});
});
rmtree $path;
ok ! -e $path;
# Die'ing inside the callback
ok (!eval { $repo = Git::Raw::Repository -> clone($remote_url, $path, {}, {
'callbacks' => {
'credentials' => sub { die "Shouldn't break!" }
}
});
});
rmtree $path;
ok ! -e $path;
# Returning undef inside the callback
ok (!eval { $repo = Git::Raw::Repository -> clone($remote_url, $path, {}, {
'callbacks' => {
'credentials' => sub { return undef; }
}
});
});
rmtree $path;
ok ! -e $path;
# Invalid key files
ok (!eval { $repo = Git::Raw::Repository -> clone($remote_url, $path, {}, {
'callbacks' => {
'credentials' => sub {
my ($url, $user) = @_;
return Git::Raw::Cred -> sshkey(
$user, 'invalid', 'invalid', 'invalid');
}
}
});
});
rmtree $path;
ok ! -e $path;
# Incorrect authentication type (username and password)
ok (!eval { $repo = Git::Raw::Repository -> clone($remote_url, $path, {}, {
'callbacks' => {
'credentials' => sub {
my ($url, $user, $types) = @_;
return Git::Raw::Cred -> userpass(
$user, 'password');
}
}
});
});
rmtree $path;
ok ! -e $path;
# Incorrect authentication type (SSH interactive)
ok (!eval { $repo = Git::Raw::Repository -> clone($remote_url, $path, {}, {
'callbacks' => {
'credentials' => sub {
my ($url, $user, $types) = @_;
return Git::Raw::Cred -> sshinteractive(
'metheunknownuser', sub {
return ('badpassword');
});
}
}
});
});
rmtree $path;
ok ! -e $path;
# Incorrect authentication type (SSH agent)
my $badCount = 0;
ok (!eval { $repo = Git::Raw::Repository -> clone($remote_url, $path, {}, {
'callbacks' => {
'credentials' => sub {
my ($url, $user, $types) = @_;
if (++$badCount >= 2) {
die "Skipping...";
}
return Git::Raw::Cred -> sshagent($user);
}
}
});
});
rmtree $path;
ok ! -e $path;
($credentials_fired, $certificate_check_fired, $update_tips_fired) = (0, 0, 0);
$repo = Git::Raw::Repository -> clone($remote_url, $path, {
'checkout_branch' => 'main'
}, {
'callbacks' => {
'credentials' => sub {
my ($url, $user) = @_;
$credentials_fired = 1;
my $ssh_dir = catfile($ENV{HOME}, '.ssh');
ok -e $ssh_dir;
my $public_key = catfile($ssh_dir, 'id_rsa.pub');
my $private_key = catfile($ssh_dir, 'id_rsa');
ok -f $public_key;
ok -f $private_key;
is $user, $ENV{USER};
t/10-clone.t view on Meta::CPAN
$update_tips_fired = 1;
like $ref, qr/refs/;
ok !defined($a);
ok defined($b);
}
}
});
ok !$repo -> is_empty;
is $credentials_fired, 1;
is $certificate_check_fired, 1;
is $update_tips_fired, 1;
@remotes = $repo -> remotes;
is $remotes[0] -> name, 'origin';
is $remotes[0] -> url, $remote_url;
@remotes = ();
$repo = undef;
t/19-push.t view on Meta::CPAN
my ($name, $instruction, @prompts) = @_;
is scalar(@prompts), 1;
my $prompt = shift @prompts;
like $prompt->{text}, qr/Password/;
is $prompt->{echo}, 0;
return ('blah');
};
my $tried_interactive = 0;
my $credentials = sub {
my ($url, $user, $types) = @_;
is ref($types), 'ARRAY';
is scalar(grep { $_ eq 'ssh_key' } @$types), 1;
is scalar(grep { $_ eq 'ssh_custom' } @$types), 1;
is scalar(grep { $_ eq 'ssh_interactive' } @$types), 1;
if (!$tried_interactive) {
$tried_interactive = 1;
return Git::Raw::Cred -> sshinteractive($user, $challenge);
t/19-push.t view on Meta::CPAN
my $public_key = File::Spec -> catfile($ssh_dir, 'id_rsa.pub');
my $private_key = File::Spec -> catfile($ssh_dir, 'id_rsa');
ok -f $public_key;
ok -f $private_key;
return Git::Raw::Cred -> sshkey($user, $public_key, $private_key);
};
$repo = Git::Raw::Repository -> clone($remote_url, $path, {}, {
'callbacks' => {
'credentials' => $credentials
}
});
ok !$repo -> is_empty;
@remotes = $repo -> remotes;
my $config = $repo -> config;
$config -> str('user.name', 'some user');
$config -> str('user.email', 'someuser@somewhere.com');
t/19-push.t view on Meta::CPAN
$index -> add('file_on_ssh_branch');
$index -> write;
my $me = Git::Raw::Signature -> default($repo);
my $commit = $repo -> commit("commit on file_on_ssh_branch\n", $me, $me, [$branch -> target],
$index -> write_tree);
is scalar(@remotes), 1;
$remote = shift @remotes;
my ($credentials_fired, $sideband_fired, $update_tips_fired) = (0, 0, 0);
my ($pack_progress_fired, $transfer_progress_fired, $status_fired) = (0, 0, 0);
my ($negotation_fired, $transport_fired) = (0, 0);
my $callbacks = {
'credentials' => sub {
$credentials_fired = 1;
return &{$credentials}(@_);
},
'sideband_progress' => sub {
my ($msg) = @_;
diag("Remote message (sideband): $msg");
is $msg, "This is from the pre-receive hook! (Disallowing it)";
$sideband_fired = 1;
},
'pack_progress' => sub {
my ($stage, $current, $total) = @_;
t/19-push.t view on Meta::CPAN
chmod 0755, $pre_receive_file;
# pre-receive hook kick
$remote -> connect('push', $callbacks);
is $remote -> push(["refs/heads/ssh_branch:refs/heads/ssh_branch"], {
'callbacks' => $callbacks
}), 1;
diag("Pre-receive hook (successfully) declined the push");
is $sideband_fired, 1;
is $credentials_fired, 1;
is $pack_progress_fired, 1;
is $transfer_progress_fired, 1;
is $status_fired, 1;
is $update_tips_fired, 0;
is $negotation_fired, 1;
is $transport_fired, 1;
# setup a pre-receive hook that succeeds
$pre_receive_content = <<'EOS';
#!/usr/bin/env perl
$|++;
print STDERR "This is from the pre-receive hook! (Allowing it)";
exit(0);
EOS
write_file($pre_receive_file, $pre_receive_content);
$callbacks = {
'credentials' => sub {
$credentials_fired = 1;
return &{$credentials}(@_);
},
'sideband_progress' => sub {
my ($msg) = @_;
diag("Remote message (sideband): $msg");
is $msg, "This is from the pre-receive hook! (Allowing it)";
$sideband_fired = 1;
},
'update_tips' => sub {
my ($ref, $a, $b) = @_;