Skip to content

Fix credential acquire callback interop #348

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 21, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions LibGit2Sharp/Core/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ internal static extern int git_config_foreach(
internal delegate int git_cred_acquire_cb(
out IntPtr cred,
IntPtr url,
IntPtr username_from_url,
uint allowed_types,
IntPtr payload);

Expand Down
15 changes: 13 additions & 2 deletions LibGit2Sharp/Network.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,11 @@ public virtual void Push(
Ensure.ArgumentNotNull(remote, "remote");
Ensure.ArgumentNotNull(pushRefSpecs, "pushRefSpecs");

// We need to keep a reference to the git_cred_acquire_cb callback around
// so it will not be garbage collected before we are done with it.
// Note that we also have a GC.KeepAlive call at the end of the method.
NativeMethods.git_cred_acquire_cb credentialCallback = null;

// Return early if there is nothing to push.
if (!pushRefSpecs.Any())
{
Expand All @@ -160,10 +165,12 @@ public virtual void Push(
{
if (credentials != null)
{
credentialCallback = (out IntPtr cred, IntPtr url, IntPtr username_from_url, uint types, IntPtr payload) =>
NativeMethods.git_cred_userpass_plaintext_new(out cred, credentials.Username, credentials.Password);

Proxy.git_remote_set_cred_acquire_cb(
remoteHandle,
(out IntPtr cred, IntPtr url, uint types, IntPtr payload) =>
NativeMethods.git_cred_userpass_plaintext_new(out cred, credentials.Username, credentials.Password),
credentialCallback,
IntPtr.Zero);
}

Expand Down Expand Up @@ -197,6 +204,10 @@ public virtual void Push(
Proxy.git_remote_disconnect(remoteHandle);
}
}

// To be safe, make sure the credential callback is kept until
// alive until at least this point.
GC.KeepAlive(credentialCallback);
}

/// <summary>
Expand Down
18 changes: 13 additions & 5 deletions LibGit2Sharp/Remote.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,22 +69,26 @@ public virtual void Fetch(
TransferProgressHandler onTransferProgress = null,
Credentials credentials = null)
{
// We need to keep a reference to the git_cred_acquire_cb callback around
// so it will not be garbage collected before we are done with it.
// Note that we also have a GC.KeepAlive call at the end of the method.
NativeMethods.git_cred_acquire_cb credentialCallback = null;

using (RemoteSafeHandle remoteHandle = Proxy.git_remote_load(repository.Handle, this.Name, true))
{
var callbacks = new RemoteCallbacks(onProgress, onCompletion, onUpdateTips);
GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks();

Proxy.git_remote_set_autotag(remoteHandle, tagFetchMode);

// Username/password auth
if (credentials != null)
{
credentialCallback = (out IntPtr cred, IntPtr url, IntPtr username_from_url, uint types, IntPtr payload) =>
NativeMethods.git_cred_userpass_plaintext_new(out cred, credentials.Username, credentials.Password);

Proxy.git_remote_set_cred_acquire_cb(
remoteHandle,
(out IntPtr cred, IntPtr url, uint types, IntPtr payload) =>
NativeMethods.git_cred_userpass_plaintext_new(out cred,
credentials.Username,
credentials.Password),
credentialCallback,
IntPtr.Zero);
}

Expand All @@ -109,6 +113,10 @@ public virtual void Fetch(
Proxy.git_remote_disconnect(remoteHandle);
}
}

// To be safe, make sure the credential callback is kept until
// alive until at least this point.
GC.KeepAlive(credentialCallback);
}

/// <summary>
Expand Down
7 changes: 6 additions & 1 deletion LibGit2Sharp/Repository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -503,11 +503,16 @@ public static Repository Clone(string sourceUrl, string workdirPath,
if (credentials != null)
{
cloneOpts.CredAcquireCallback =
(out IntPtr cred, IntPtr url, uint types, IntPtr payload) =>
(out IntPtr cred, IntPtr url, IntPtr username_from_url, uint types, IntPtr payload) =>
NativeMethods.git_cred_userpass_plaintext_new(out cred, credentials.Username, credentials.Password);
}

using(Proxy.git_clone(sourceUrl, workdirPath, cloneOpts)) {}

// To be safe, make sure the credential callback is kept until
// alive until at least this point.
GC.KeepAlive(cloneOpts.CredAcquireCallback);

return new Repository(workdirPath, options);
}

Expand Down