Unverified Commit f7325c44 by Edward Thomson Committed by GitHub

Merge pull request #6503 from fxcoudert/hostandport

Pass hostkey & port to host verify callback
parents cfc3b379 43e84e24
...@@ -651,6 +651,8 @@ static int check_against_known_hosts( ...@@ -651,6 +651,8 @@ static int check_against_known_hosts(
return ret; return ret;
} }
#define SSH_DEFAULT_PORT 22
/* /*
* Perform the check for the session's certificate against known hosts if * Perform the check for the session's certificate against known hosts if
* possible and then ask the user if they have a callback. * possible and then ask the user if they have a callback.
...@@ -748,9 +750,16 @@ static int check_certificate( ...@@ -748,9 +750,16 @@ static int check_certificate(
if (check_cb != NULL) { if (check_cb != NULL) {
git_cert_hostkey *cert_ptr = &cert; git_cert_hostkey *cert_ptr = &cert;
git_error_state previous_error = {0}; git_error_state previous_error = {0};
const char *host_ptr = host;
git_str host_and_port = GIT_STR_INIT;
if (port != SSH_DEFAULT_PORT) {
git_str_printf(&host_and_port, "%s:%d", host, port);
host_ptr = host_and_port.ptr;
}
git_error_state_capture(&previous_error, error); git_error_state_capture(&previous_error, error);
error = check_cb((git_cert *) cert_ptr, cert_valid, host, check_cb_payload); error = check_cb((git_cert *) cert_ptr, cert_valid, host_ptr, check_cb_payload);
if (error == GIT_PASSTHROUGH) { if (error == GIT_PASSTHROUGH) {
error = git_error_state_restore(&previous_error); error = git_error_state_restore(&previous_error);
} else if (error < 0 && !git_error_last()) { } else if (error < 0 && !git_error_last()) {
...@@ -758,13 +767,12 @@ static int check_certificate( ...@@ -758,13 +767,12 @@ static int check_certificate(
} }
git_error_state_free(&previous_error); git_error_state_free(&previous_error);
git_str_dispose(&host_and_port);
} }
return error; return error;
} }
#define SSH_DEFAULT_PORT "22"
static int _git_ssh_setup_conn( static int _git_ssh_setup_conn(
ssh_subtransport *t, ssh_subtransport *t,
const char *url, const char *url,
...@@ -788,15 +796,8 @@ static int _git_ssh_setup_conn( ...@@ -788,15 +796,8 @@ static int _git_ssh_setup_conn(
s->session = NULL; s->session = NULL;
s->channel = NULL; s->channel = NULL;
if (git_net_str_is_url(url)) if ((error = git_net_url_parse_standard_or_scp(&s->url, url)) < 0 ||
error = git_net_url_parse(&s->url, url); (error = git_socket_stream_new(&s->io, s->url.host, s->url.port)) < 0 ||
else
error = git_net_url_parse_scp(&s->url, url);
if (error < 0)
goto done;
if ((error = git_socket_stream_new(&s->io, s->url.host, s->url.port)) < 0 ||
(error = git_stream_connect(s->io)) < 0) (error = git_stream_connect(s->io)) < 0)
goto done; goto done;
...@@ -806,8 +807,11 @@ static int _git_ssh_setup_conn( ...@@ -806,8 +807,11 @@ static int _git_ssh_setup_conn(
* as part of the stream connection, but that's not something that's * as part of the stream connection, but that's not something that's
* exposed. * exposed.
*/ */
if (git__strntol32(&port, s->url.port, strlen(s->url.port), NULL, 10) < 0) if (git__strntol32(&port, s->url.port, strlen(s->url.port), NULL, 10) < 0) {
port = -1; git_error_set(GIT_ERROR_NET, "invalid port to ssh: %s", s->url.port);
error = -1;
goto done;
}
if ((error = _git_ssh_session_create(&session, &known_hosts, s->url.host, port, s->io)) < 0) if ((error = _git_ssh_session_create(&session, &known_hosts, s->url.host, port, s->io)) < 0)
goto done; goto done;
......
...@@ -646,6 +646,13 @@ int git_net_url_parse_scp(git_net_url *url, const char *given) ...@@ -646,6 +646,13 @@ int git_net_url_parse_scp(git_net_url *url, const char *given)
return 0; return 0;
} }
int git_net_url_parse_standard_or_scp(git_net_url *url, const char *given)
{
return git_net_str_is_url(given) ?
git_net_url_parse(url, given) :
git_net_url_parse_scp(url, given);
}
int git_net_url_joinpath( int git_net_url_joinpath(
git_net_url *out, git_net_url *out,
git_net_url *one, git_net_url *one,
......
...@@ -34,6 +34,12 @@ extern int git_net_url_parse(git_net_url *url, const char *str); ...@@ -34,6 +34,12 @@ extern int git_net_url_parse(git_net_url *url, const char *str);
/** Parses a string containing an SCP style path into a URL structure. */ /** Parses a string containing an SCP style path into a URL structure. */
extern int git_net_url_parse_scp(git_net_url *url, const char *str); extern int git_net_url_parse_scp(git_net_url *url, const char *str);
/**
* Parses a string containing a standard URL or an SCP style path into
* a URL structure.
*/
extern int git_net_url_parse_standard_or_scp(git_net_url *url, const char *str);
/** Appends a path and/or query string to the given URL */ /** Appends a path and/or query string to the given URL */
extern int git_net_url_joinpath( extern int git_net_url_joinpath(
git_net_url *out, git_net_url *out,
......
...@@ -787,10 +787,19 @@ static int ssh_certificate_check(git_cert *cert, int valid, const char *host, vo ...@@ -787,10 +787,19 @@ static int ssh_certificate_check(git_cert *cert, int valid, const char *host, vo
{ {
git_cert_hostkey *key; git_cert_hostkey *key;
git_oid expected = GIT_OID_SHA1_ZERO, actual = GIT_OID_SHA1_ZERO; git_oid expected = GIT_OID_SHA1_ZERO, actual = GIT_OID_SHA1_ZERO;
git_str expected_host = GIT_STR_INIT;
git_net_url parsed_url = GIT_NET_URL_INIT;
GIT_UNUSED(valid); GIT_UNUSED(valid);
GIT_UNUSED(payload); GIT_UNUSED(payload);
cl_git_pass(git_net_url_parse_standard_or_scp(&parsed_url, _remote_url));
cl_git_pass(git_str_printf(&expected_host, "%s%s%s",
parsed_url.host,
git_net_url_is_default_port(&parsed_url) ? "" : ":",
git_net_url_is_default_port(&parsed_url) ? "" : parsed_url.port));
cl_assert_equal_s(expected_host.ptr, host);
cl_assert(_remote_ssh_fingerprint); cl_assert(_remote_ssh_fingerprint);
cl_git_pass(git_oid__fromstrp(&expected, _remote_ssh_fingerprint, GIT_OID_SHA1)); cl_git_pass(git_oid__fromstrp(&expected, _remote_ssh_fingerprint, GIT_OID_SHA1));
...@@ -812,7 +821,8 @@ static int ssh_certificate_check(git_cert *cert, int valid, const char *host, vo ...@@ -812,7 +821,8 @@ static int ssh_certificate_check(git_cert *cert, int valid, const char *host, vo
cl_assert(!memcmp(&expected, &actual, 20)); cl_assert(!memcmp(&expected, &actual, 20));
cl_assert_equal_s("localhost", host); git_net_url_dispose(&parsed_url);
git_str_dispose(&expected_host);
return GIT_EUSER; return GIT_EUSER;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment