예제 #1
0
int openssl_connect(git_stream *stream)
{
	int ret;
	BIO *bio;
	openssl_stream *st = (openssl_stream *) stream;

	if ((ret = git_stream_connect(st->io)) < 0)
		return ret;

	st->connected = true;

	bio = BIO_new(&git_stream_bio_method);
	GITERR_CHECK_ALLOC(bio);
	bio->ptr = st->io;

	SSL_set_bio(st->ssl, bio, bio);
	/* specify the host in case SNI is needed */
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
	SSL_set_tlsext_host_name(st->ssl, st->host);
#endif

	if ((ret = SSL_connect(st->ssl)) <= 0)
		return ssl_set_error(st->ssl, ret);

	return verify_server_cert(st->ssl, st->host);
}
예제 #2
0
파일: stransport.c 프로젝트: csware/libgit2
static int stransport_connect(git_stream *stream)
{
	stransport_stream *st = (stransport_stream *) stream;
	int error;
	SecTrustRef trust = NULL;
	SecTrustResultType sec_res;
	OSStatus ret;

	if ((error = git_stream_connect(st->io)) < 0)
		return error;

	ret = SSLHandshake(st->ctx);
	if (ret != errSSLServerAuthCompleted) {
		giterr_set(GITERR_SSL, "unexpected return value from ssl handshake %d", (int)ret);
		return -1;
	}

	if ((ret = SSLCopyPeerTrust(st->ctx, &trust)) != noErr)
		goto on_error;

	if (!trust)
		return GIT_ECERTIFICATE;

	if ((ret = SecTrustEvaluate(trust, &sec_res)) != noErr)
		goto on_error;

	CFRelease(trust);

	if (sec_res == kSecTrustResultInvalid || sec_res == kSecTrustResultOtherError) {
		giterr_set(GITERR_SSL, "internal security trust error");
		return -1;
	}

	if (sec_res == kSecTrustResultDeny || sec_res == kSecTrustResultRecoverableTrustFailure ||
	    sec_res == kSecTrustResultFatalTrustFailure) {
		giterr_set(GITERR_SSL, "untrusted connection error");
		return GIT_ECERTIFICATE;
	}

	return 0;

on_error:
	if (trust)
		CFRelease(trust);

	return stransport_error(ret);
}
예제 #3
0
int openssl_connect(git_stream *stream)
{
	int ret;
	openssl_stream *st = (openssl_stream *) stream;

	if ((ret = git_stream_connect((git_stream *)st->socket)) < 0)
		return ret;

	if ((ret = SSL_set_fd(st->ssl, st->socket->s)) <= 0) {
		openssl_close((git_stream *) st);
		return ssl_set_error(st->ssl, ret);
	}

	if ((ret = SSL_connect(st->ssl)) <= 0)
		return ssl_set_error(st->ssl, ret);

	return verify_server_cert(st->ssl, st->socket->host);
}
예제 #4
0
파일: git.c 프로젝트: ethomson/libgit2
static int _git_uploadpack_ls(
	git_subtransport *t,
	const char *url,
	git_smart_subtransport_stream **stream)
{
	char *host=NULL, *port=NULL, *path=NULL, *user=NULL, *pass=NULL;
	const char *stream_url = url;
	git_proto_stream *s;
	int error;

	*stream = NULL;

	if (!git__prefixcmp(url, prefix_git))
		stream_url += strlen(prefix_git);

	if ((error = gitno_extract_url_parts(&host, &port, &path, &user, &pass, url, GIT_DEFAULT_PORT)) < 0)
		return error;

	error = git_proto_stream_alloc(t, stream_url, cmd_uploadpack, host, port, stream);

	git__free(host);
	git__free(port);
	git__free(path);
	git__free(user);
	git__free(pass);


	if (error < 0) {
		git_proto_stream_free(*stream);
		return error;
	}

	s = (git_proto_stream *) *stream;
	if ((error = git_stream_connect(s->io)) < 0) {
		git_proto_stream_free(*stream);
		return error;
	}

	t->current_stream = s;

	return 0;
}
예제 #5
0
int openssl_connect(git_stream *stream)
{
	int ret;
	openssl_stream *st = (openssl_stream *) stream;

	if ((ret = git_stream_connect((git_stream *)st->socket)) < 0)
		return ret;

	if ((ret = SSL_set_fd(st->ssl, st->socket->s)) <= 0) {
		openssl_close((git_stream *) st);
		return ssl_set_error(st->ssl, ret);
	}

	/* specify the host in case SNI is needed */
	SSL_set_tlsext_host_name(st->ssl, st->socket->host);

	if ((ret = SSL_connect(st->ssl)) <= 0)
		return ssl_set_error(st->ssl, ret);

	return verify_server_cert(st->ssl, st->socket->host);
}
예제 #6
0
파일: ssh.c 프로젝트: Nemchinovrp/sonic-pi
static int _git_ssh_setup_conn(
	ssh_subtransport *t,
	const char *url,
	const char *cmd,
	git_smart_subtransport_stream **stream)
{
	char *host=NULL, *port=NULL, *path=NULL, *user=NULL, *pass=NULL;
	const char *default_port="22";
	int auth_methods, error = 0;
	size_t i;
	ssh_stream *s;
	git_cred *cred = NULL;
	LIBSSH2_SESSION* session=NULL;
	LIBSSH2_CHANNEL* channel=NULL;

	t->current_stream = NULL;

	*stream = NULL;
	if (ssh_stream_alloc(t, url, cmd, stream) < 0)
		return -1;

	s = (ssh_stream *)*stream;
	s->session = NULL;
	s->channel = NULL;

	for (i = 0; i < ARRAY_SIZE(ssh_prefixes); ++i) {
		const char *p = ssh_prefixes[i];

		if (!git__prefixcmp(url, p)) {
			if ((error = gitno_extract_url_parts(&host, &port, &path, &user, &pass, url, default_port)) < 0)
				goto done;

			goto post_extract;
		}
	}
	if ((error = git_ssh_extract_url_parts(&host, &user, url)) < 0)
		goto done;
	port = git__strdup(default_port);
	GITERR_CHECK_ALLOC(port);

post_extract:
	if ((error = git_socket_stream_new(&s->io, host, port)) < 0 ||
	    (error = git_stream_connect(s->io)) < 0)
		goto done;

	if ((error = _git_ssh_session_create(&session, s->io)) < 0)
		goto done;

	if (t->owner->certificate_check_cb != NULL) {
		git_cert_hostkey cert = {{ 0 }}, *cert_ptr;
		const char *key;

		cert.parent.cert_type = GIT_CERT_HOSTKEY_LIBSSH2;

		key = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
		if (key != NULL) {
			cert.type |= GIT_CERT_SSH_SHA1;
			memcpy(&cert.hash_sha1, key, 20);
		}

		key = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
		if (key != NULL) {
			cert.type |= GIT_CERT_SSH_MD5;
			memcpy(&cert.hash_md5, key, 16);
		}

		if (cert.type == 0) {
			giterr_set(GITERR_SSH, "unable to get the host key");
			error = -1;
			goto done;
		}

		/* We don't currently trust any hostkeys */
		giterr_clear();

		cert_ptr = &cert;

		error = t->owner->certificate_check_cb((git_cert *) cert_ptr, 0, host, t->owner->message_cb_payload);
		if (error < 0) {
			if (!giterr_last())
				giterr_set(GITERR_NET, "user cancelled hostkey check");

			goto done;
		}
	}

	/* we need the username to ask for auth methods */
	if (!user) {
		if ((error = request_creds(&cred, t, NULL, GIT_CREDTYPE_USERNAME)) < 0)
			goto done;

		user = git__strdup(((git_cred_username *) cred)->username);
		cred->free(cred);
		cred = NULL;
		if (!user)
			goto done;
	} else if (user && pass) {
		if ((error = git_cred_userpass_plaintext_new(&cred, user, pass)) < 0)
			goto done;
	}

	if ((error = list_auth_methods(&auth_methods, session, user)) < 0)
		goto done;

	error = GIT_EAUTH;
	/* if we already have something to try */
	if (cred && auth_methods & cred->credtype)
		error = _git_ssh_authenticate_session(session, cred);

	while (error == GIT_EAUTH) {
		if (cred) {
			cred->free(cred);
			cred = NULL;
		}

		if ((error = request_creds(&cred, t, user, auth_methods)) < 0)
			goto done;

		if (strcmp(user, git_cred__username(cred))) {
			giterr_set(GITERR_SSH, "username does not match previous request");
			error = -1;
			goto done;
		}

		error = _git_ssh_authenticate_session(session, cred);
	}

	if (error < 0)
		goto done;

	channel = libssh2_channel_open_session(session);
	if (!channel) {
		error = -1;
		ssh_error(session, "Failed to open SSH channel");
		goto done;
	}

	libssh2_channel_set_blocking(channel, 1);

	s->session = session;
	s->channel = channel;

	t->current_stream = s;

done:
	if (error < 0) {
		ssh_stream_free(*stream);

		if (session)
			libssh2_session_free(session);
	}

	if (cred)
		cred->free(cred);

	git__free(host);
	git__free(port);
	git__free(path);
	git__free(user);
	git__free(pass);

	return error;
}