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 )