Git-Raw
view release on metacpan or search on metacpan
deps/libgit2/src/libgit2/transports/ssh.c view on Meta::CPAN
/* ideally, we should be able to set this by calling
* libssh2_session_init_ex() instead of libssh2_session_init().
* libssh2's API is inconsistent here i.e. libssh2_userauth_publickey()
* allows you to pass the `abstract` as part of the call, whereas
* libssh2_userauth_keyboard_interactive() does not!
*
* The only way to set the `abstract` pointer is by calling
* libssh2_session_abstract(), which will replace the existing
* pointer as is done below. This is safe for now (at time of writing),
* but may not be valid in future.
*/
*abstract = c->payload;
rc = libssh2_userauth_keyboard_interactive(
session, c->username, c->prompt_callback);
break;
}
#ifdef GIT_SSH_MEMORY_CREDENTIALS
case GIT_CREDENTIAL_SSH_MEMORY: {
git_credential_ssh_key *c = (git_credential_ssh_key *)cred;
GIT_ASSERT(c->username);
GIT_ASSERT(c->privatekey);
rc = libssh2_userauth_publickey_frommemory(
session,
c->username,
strlen(c->username),
c->publickey,
c->publickey ? strlen(c->publickey) : 0,
c->privatekey,
strlen(c->privatekey),
c->passphrase);
break;
}
#endif
default:
rc = LIBSSH2_ERROR_AUTHENTICATION_FAILED;
}
} while (LIBSSH2_ERROR_EAGAIN == rc || LIBSSH2_ERROR_TIMEOUT == rc);
if (rc == LIBSSH2_ERROR_PASSWORD_EXPIRED ||
rc == LIBSSH2_ERROR_AUTHENTICATION_FAILED ||
rc == LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED)
return GIT_EAUTH;
if (rc != LIBSSH2_ERROR_NONE) {
if (!git_error_last())
ssh_error(session, "Failed to authenticate SSH session");
return -1;
}
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,
git_stream *io)
{
int rc = 0;
LIBSSH2_SESSION *s;
git_socket_stream *socket = GIT_CONTAINER_OF(io, git_socket_stream, parent);
GIT_ASSERT_ARG(session);
s = libssh2_session_init();
if (!s) {
git_error_set(GIT_ERROR_NET, "failed to initialize SSH session");
return -1;
}
do {
rc = libssh2_session_handshake(s, socket->s);
} while (LIBSSH2_ERROR_EAGAIN == rc || LIBSSH2_ERROR_TIMEOUT == rc);
if (rc != LIBSSH2_ERROR_NONE) {
ssh_error(s, "failed to start SSH session");
libssh2_session_free(s);
return -1;
}
libssh2_session_set_blocking(s, 1);
*session = s;
return 0;
}
#define SSH_DEFAULT_PORT "22"
static int _git_ssh_setup_conn(
ssh_subtransport *t,
const char *url,
const char *cmd,
git_smart_subtransport_stream **stream)
{
int auth_methods, error = 0;
ssh_stream *s;
git_credential *cred = NULL;
LIBSSH2_SESSION *session=NULL;
LIBSSH2_CHANNEL *channel=NULL;
t->current_stream = NULL;
*stream = NULL;
if (ssh_stream_alloc(t, cmd, stream) < 0)
return -1;
( run in 0.664 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )