summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@microsoft.com>2014-10-13 15:43:03 -0400
committerEdward Thomson <ethomson@microsoft.com>2014-10-26 22:27:46 -0400
commitbc42479aaa789eee07af73dc094180f13dd13a63 (patch)
tree52211469b36d0841e52045916a361b88fcd5cdc0
parentcdd71711cedd3c79a10f75ea8ff98c3979bf6c6c (diff)
downloadlibgit2-bc42479aaa789eee07af73dc094180f13dd13a63.tar.gz
Cleanup memory leak in ssh transport
-rw-r--r--src/transports/ssh.c62
1 files changed, 28 insertions, 34 deletions
diff --git a/src/transports/ssh.c b/src/transports/ssh.c
index 39e4e3d15..1f6716f5d 100644
--- a/src/transports/ssh.c
+++ b/src/transports/ssh.c
@@ -457,27 +457,31 @@ static int _git_ssh_setup_conn(
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;
if (!git__prefixcmp(url, prefix_ssh)) {
if ((error = gitno_extract_url_parts(&host, &port, &path, &user, &pass, url, default_port)) < 0)
- goto on_error;
+ goto done;
} else {
if ((error = git_ssh_extract_url_parts(&host, &user, url)) < 0)
- goto on_error;
+ goto done;
port = git__strdup(default_port);
GITERR_CHECK_ALLOC(port);
}
if ((error = gitno_connect(&s->socket, host, port, 0)) < 0)
- goto on_error;
+ goto done;
if ((error = _git_ssh_session_create(&session, s->socket)) < 0)
- goto on_error;
+ goto done;
if (t->owner->certificate_check_cb != NULL) {
git_cert_hostkey cert = { 0 }, *cert_ptr;
@@ -499,7 +503,8 @@ static int _git_ssh_setup_conn(
if (cert.type == 0) {
giterr_set(GITERR_SSH, "unable to get the host key");
- return -1;
+ error = -1;
+ goto done;
}
/* We don't currently trust any hostkeys */
@@ -512,27 +517,27 @@ static int _git_ssh_setup_conn(
if (!giterr_last())
giterr_set(GITERR_NET, "user cancelled hostkey check");
- goto on_error;
+ 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 on_error;
+ goto done;
user = git__strdup(((git_cred_username *) cred)->username);
cred->free(cred);
cred = NULL;
if (!user)
- goto on_error;
+ goto done;
} else if (user && pass) {
if ((error = git_cred_userpass_plaintext_new(&cred, user, pass)) < 0)
- goto on_error;
+ goto done;
}
if ((error = list_auth_methods(&auth_methods, session, user)) < 0)
- goto on_error;
+ goto done;
error = GIT_EAUTH;
/* if we already have something to try */
@@ -546,25 +551,25 @@ static int _git_ssh_setup_conn(
}
if ((error = request_creds(&cred, t, user, auth_methods)) < 0)
- goto on_error;
+ goto done;
if (strcmp(user, git_cred__username(cred))) {
giterr_set(GITERR_SSH, "username does not match previous request");
error = -1;
- goto on_error;
+ goto done;
}
error = _git_ssh_authenticate_session(session, cred);
}
if (error < 0)
- goto on_error;
+ goto done;
channel = libssh2_channel_open_session(session);
if (!channel) {
error = -1;
ssh_error(session, "Failed to open SSH channel");
- goto on_error;
+ goto done;
}
libssh2_channel_set_blocking(channel, 1);
@@ -573,36 +578,25 @@ static int _git_ssh_setup_conn(
s->channel = channel;
t->current_stream = s;
- if (cred)
- cred->free(cred);
- git__free(host);
- git__free(port);
- git__free(path);
- git__free(user);
- git__free(pass);
-
- return 0;
+done:
+ if (error < 0) {
+ if (*stream)
+ ssh_stream_free(*stream);
-on_error:
- s->session = NULL;
- s->channel = NULL;
- t->current_stream = NULL;
-
- if (*stream)
- 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);
- if (session)
- libssh2_session_free(session);
-
return error;
}