From 888a3de22141b74d8929f33bccac9980d8e4ece8 Mon Sep 17 00:00:00 2001 From: Adrian Roman Date: Thu, 19 Aug 2021 14:19:35 +0300 Subject: [PATCH 1/4] Changes to support ssh and libgit2-1.1.1 (avoiding deprecated calls, too). --- LibGit2Sharp.Tests/CloneFixture.cs | 2 +- LibGit2Sharp.Tests/FetchFixture.cs | 8 +- LibGit2Sharp.Tests/GlobalSettingsFixture.cs | 2 +- LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj | 20 ++- .../LibGit2Sharp.Tests.v2.ncrunchproject | 4 +- LibGit2Sharp.Tests/MetaFixture.cs | 2 +- LibGit2Sharp.sln | 18 +++ LibGit2Sharp/Branch.cs | 2 +- LibGit2Sharp/Core/EncodingMarshaler.cs | 1 + LibGit2Sharp/Core/GitRemoteCallbacks.cs | 2 +- LibGit2Sharp/Core/GitStrArrayNative.cs | 2 +- LibGit2Sharp/Core/NativeMethods.cs | 30 ++-- LibGit2Sharp/Core/Proxy.cs | 35 +++-- LibGit2Sharp/DefaultCredentials.cs | 2 +- LibGit2Sharp/LibGit2Sharp.csproj | 16 +- LibGit2Sharp/ObjectDatabase.cs | 8 +- LibGit2Sharp/OdbBackend.cs | 2 +- LibGit2Sharp/RemoteCallbacks.cs | 21 +++ .../SecureUsernamePasswordCredentials.cs | 2 +- LibGit2Sharp/SshCredentials.cs | 144 ++++++++++++++++++ LibGit2Sharp/SupportedCredentialTypes.cs | 62 ++++++-- LibGit2Sharp/UsernamePasswordCredentials.cs | 2 +- NativeLibraryLoadTestApp/TestApp.cs | 11 +- .../x64/NativeLibraryLoadTestApp.x64.csproj | 3 +- .../x86/NativeLibraryLoadTestApp.x86.csproj | 3 +- Targets/CodeGenerator.targets | 4 +- Targets/GenerateNativeDllName.targets | 2 +- global.json | 2 +- 28 files changed, 332 insertions(+), 80 deletions(-) create mode 100644 LibGit2Sharp/SshCredentials.cs diff --git a/LibGit2Sharp.Tests/CloneFixture.cs b/LibGit2Sharp.Tests/CloneFixture.cs index bbe6a7f33..53becf6c4 100644 --- a/LibGit2Sharp.Tests/CloneFixture.cs +++ b/LibGit2Sharp.Tests/CloneFixture.cs @@ -70,7 +70,7 @@ private void AssertLocalClone(string url, string path = null, bool isCloningAnEm Assert.NotEqual(originalRepo.Info.Path, clonedRepo.Info.Path); Assert.Equal(originalRepo.Head, clonedRepo.Head); - Assert.Equal(originalRepo.Branches.Count(), clonedRepo.Branches.Count(b => b.IsRemote)); + Assert.Equal(originalRepo.Branches.Count(), clonedRepo.Branches.Count(b => (b.IsRemote && !b.CanonicalName.Equals("refs/remotes/origin/HEAD")))); Assert.Equal(isCloningAnEmptyRepository ? 0 : 1, clonedRepo.Branches.Count(b => !b.IsRemote)); Assert.Equal(originalRepo.Tags.Count(), clonedRepo.Tags.Count()); diff --git a/LibGit2Sharp.Tests/FetchFixture.cs b/LibGit2Sharp.Tests/FetchFixture.cs index 170b64d61..795c65029 100644 --- a/LibGit2Sharp.Tests/FetchFixture.cs +++ b/LibGit2Sharp.Tests/FetchFixture.cs @@ -215,7 +215,7 @@ public void FetchHonorsTheFetchPruneConfigurationEntry() using (var clonedRepo = new Repository(clonedRepoPath)) { - Assert.Equal(5, clonedRepo.Branches.Count(b => b.IsRemote)); + Assert.Equal(5, clonedRepo.Branches.Count(b => (b.IsRemote && !b.CanonicalName.Equals("refs/remotes/origin/HEAD")))); // Drop one of the branches in the remote repository using (var sourceRepo = new Repository(source)) @@ -226,17 +226,17 @@ public void FetchHonorsTheFetchPruneConfigurationEntry() // No pruning when the configuration entry isn't defined Assert.Null(clonedRepo.Config.Get("fetch.prune")); Commands.Fetch(clonedRepo, "origin", new string[0], null, null); - Assert.Equal(5, clonedRepo.Branches.Count(b => b.IsRemote)); + Assert.Equal(5, clonedRepo.Branches.Count(b => (b.IsRemote && !b.CanonicalName.Equals("refs/remotes/origin/HEAD")))); // No pruning when the configuration entry is set to false clonedRepo.Config.Set("fetch.prune", false); Commands.Fetch(clonedRepo, "origin", new string[0], null, null); - Assert.Equal(5, clonedRepo.Branches.Count(b => b.IsRemote)); + Assert.Equal(5, clonedRepo.Branches.Count(b => (b.IsRemote && !b.CanonicalName.Equals("refs/remotes/origin/HEAD")))); // Auto pruning when the configuration entry is set to true clonedRepo.Config.Set("fetch.prune", true); Commands.Fetch(clonedRepo, "origin", new string[0], null, null); - Assert.Equal(4, clonedRepo.Branches.Count(b => b.IsRemote)); + Assert.Equal(4, clonedRepo.Branches.Count(b => (b.IsRemote && !b.CanonicalName.Equals("refs/remotes/origin/HEAD")))); } } diff --git a/LibGit2Sharp.Tests/GlobalSettingsFixture.cs b/LibGit2Sharp.Tests/GlobalSettingsFixture.cs index 6026f267a..d6602fa79 100644 --- a/LibGit2Sharp.Tests/GlobalSettingsFixture.cs +++ b/LibGit2Sharp.Tests/GlobalSettingsFixture.cs @@ -32,7 +32,7 @@ public void CanRetrieveValidVersionString() // git2SharpHash: '871d13a67f' LibGit2Sharp hash. // arch: 'x86' or 'x64' libgit2 target. // git2Features: 'Threads, Ssh' libgit2 features compiled with. - string regex = @"^(?\d+\.\d+\.\d+(-[\w\-\.]+)?\+((?[a-f0-9]{10})\.)?libgit2-[a-f0-9]{7}) \((?\w+) - (?(?:\w*(?:, )*\w+)*)\)$"; + string regex = @"^(?\d+\.\d+\.\d+(-[\w\-\.]+)?\+((?[a-f0-9]{10})\.)?libgit2) \((?\w+) - (?(?:\w*(?:, )*\w+)*)\)$"; Assert.NotNull(versionInfo); diff --git a/LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj b/LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj index 1810df2ee..a9c2e0ac0 100644 --- a/LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj +++ b/LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj @@ -1,18 +1,26 @@  - net472;netcoreapp2.1;net5.0 + net48 + AnyCPU;x64 + + + + + x64 - - + - - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + @@ -22,7 +30,7 @@ - + diff --git a/LibGit2Sharp.Tests/LibGit2Sharp.Tests.v2.ncrunchproject b/LibGit2Sharp.Tests/LibGit2Sharp.Tests.v2.ncrunchproject index e24470157..380921d15 100644 --- a/LibGit2Sharp.Tests/LibGit2Sharp.Tests.v2.ncrunchproject +++ b/LibGit2Sharp.Tests/LibGit2Sharp.Tests.v2.ncrunchproject @@ -21,11 +21,11 @@ AutoDetect STA - x86 + x64 LibGit2Sharp.Tests.ShadowCopyFixture.CanProbeForNativeBinariesFromAShadowCopiedAssembly Resources\**;Resources\**.* - \ No newline at end of file + diff --git a/LibGit2Sharp.Tests/MetaFixture.cs b/LibGit2Sharp.Tests/MetaFixture.cs index b70d9022c..127445158 100644 --- a/LibGit2Sharp.Tests/MetaFixture.cs +++ b/LibGit2Sharp.Tests/MetaFixture.cs @@ -306,7 +306,7 @@ public void NoPublicTypesUnderLibGit2SharpCoreNamespace() // Ugly hack to circumvent a Mono bug // cf. https://bugzilla.xamarin.com/show_bug.cgi?id=27010 .Where(t => !t.FullName.Contains("+")) - .Where(t => t.FullName != "LibGit2Sharp.Core.LeaksContainer") + .Where(t => (t.FullName != "LibGit2Sharp.Core.LeaksContainer" && t.FullName != "LibGit2Sharp.Core.NativeDllName")) .ToList(); if (types.Any()) diff --git a/LibGit2Sharp.sln b/LibGit2Sharp.sln index a81b0ce37..765646170 100644 --- a/LibGit2Sharp.sln +++ b/LibGit2Sharp.sln @@ -23,25 +23,43 @@ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {EE6ED99F-CB12-4683-B055-D28FC7357A34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EE6ED99F-CB12-4683-B055-D28FC7357A34}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EE6ED99F-CB12-4683-B055-D28FC7357A34}.Debug|x64.ActiveCfg = Debug|x64 + {EE6ED99F-CB12-4683-B055-D28FC7357A34}.Debug|x64.Build.0 = Debug|x64 {EE6ED99F-CB12-4683-B055-D28FC7357A34}.Release|Any CPU.ActiveCfg = Release|Any CPU {EE6ED99F-CB12-4683-B055-D28FC7357A34}.Release|Any CPU.Build.0 = Release|Any CPU + {EE6ED99F-CB12-4683-B055-D28FC7357A34}.Release|x64.ActiveCfg = Release|x64 + {EE6ED99F-CB12-4683-B055-D28FC7357A34}.Release|x64.Build.0 = Release|x64 {286E63EB-04DD-4ADE-88D6-041B57800761}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {286E63EB-04DD-4ADE-88D6-041B57800761}.Debug|Any CPU.Build.0 = Debug|Any CPU + {286E63EB-04DD-4ADE-88D6-041B57800761}.Debug|x64.ActiveCfg = Debug|x64 + {286E63EB-04DD-4ADE-88D6-041B57800761}.Debug|x64.Build.0 = Debug|x64 {286E63EB-04DD-4ADE-88D6-041B57800761}.Release|Any CPU.ActiveCfg = Release|Any CPU {286E63EB-04DD-4ADE-88D6-041B57800761}.Release|Any CPU.Build.0 = Release|Any CPU + {286E63EB-04DD-4ADE-88D6-041B57800761}.Release|x64.ActiveCfg = Release|x64 + {286E63EB-04DD-4ADE-88D6-041B57800761}.Release|x64.Build.0 = Release|x64 {86453D2C-4953-4DF4-B12A-ADE579608BAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {86453D2C-4953-4DF4-B12A-ADE579608BAA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {86453D2C-4953-4DF4-B12A-ADE579608BAA}.Debug|x64.ActiveCfg = Debug|x64 + {86453D2C-4953-4DF4-B12A-ADE579608BAA}.Debug|x64.Build.0 = Debug|x64 {86453D2C-4953-4DF4-B12A-ADE579608BAA}.Release|Any CPU.ActiveCfg = Release|Any CPU {86453D2C-4953-4DF4-B12A-ADE579608BAA}.Release|Any CPU.Build.0 = Release|Any CPU + {86453D2C-4953-4DF4-B12A-ADE579608BAA}.Release|x64.ActiveCfg = Release|x64 + {86453D2C-4953-4DF4-B12A-ADE579608BAA}.Release|x64.Build.0 = Release|x64 {5C55175D-6A1F-4C51-B791-BF7DD00124EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5C55175D-6A1F-4C51-B791-BF7DD00124EE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5C55175D-6A1F-4C51-B791-BF7DD00124EE}.Debug|x64.ActiveCfg = Debug|x64 + {5C55175D-6A1F-4C51-B791-BF7DD00124EE}.Debug|x64.Build.0 = Debug|x64 {5C55175D-6A1F-4C51-B791-BF7DD00124EE}.Release|Any CPU.ActiveCfg = Release|Any CPU {5C55175D-6A1F-4C51-B791-BF7DD00124EE}.Release|Any CPU.Build.0 = Release|Any CPU + {5C55175D-6A1F-4C51-B791-BF7DD00124EE}.Release|x64.ActiveCfg = Release|x64 + {5C55175D-6A1F-4C51-B791-BF7DD00124EE}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/LibGit2Sharp/Branch.cs b/LibGit2Sharp/Branch.cs index 807456688..df4532f30 100644 --- a/LibGit2Sharp/Branch.cs +++ b/LibGit2Sharp/Branch.cs @@ -244,7 +244,7 @@ private static bool IsRemoteBranch(string canonicalName) } /// - /// Removes redundent leading namespaces (regarding the kind of + /// Removes redundant leading namespaces (regarding the kind of /// reference being wrapped) from the canonical name. /// /// The friendly shortened name diff --git a/LibGit2Sharp/Core/EncodingMarshaler.cs b/LibGit2Sharp/Core/EncodingMarshaler.cs index 0cafd9aa1..cf167387d 100644 --- a/LibGit2Sharp/Core/EncodingMarshaler.cs +++ b/LibGit2Sharp/Core/EncodingMarshaler.cs @@ -166,4 +166,5 @@ public static string FromBuffer(Encoding encoding, byte[] buffer, int length) return encoding.GetString(buffer, 0, length); } } + } diff --git a/LibGit2Sharp/Core/GitRemoteCallbacks.cs b/LibGit2Sharp/Core/GitRemoteCallbacks.cs index 54cdb46ed..6e9b527a2 100644 --- a/LibGit2Sharp/Core/GitRemoteCallbacks.cs +++ b/LibGit2Sharp/Core/GitRemoteCallbacks.cs @@ -15,7 +15,7 @@ internal struct GitRemoteCallbacks internal NativeMethods.remote_completion_callback completion; - internal NativeMethods.git_cred_acquire_cb acquire_credentials; + internal NativeMethods.git_credential_acquire_cb acquire_credentials; internal NativeMethods.git_transport_certificate_check_cb certificate_check; diff --git a/LibGit2Sharp/Core/GitStrArrayNative.cs b/LibGit2Sharp/Core/GitStrArrayNative.cs index 8813f8e6e..f64734073 100644 --- a/LibGit2Sharp/Core/GitStrArrayNative.cs +++ b/LibGit2Sharp/Core/GitStrArrayNative.cs @@ -33,7 +33,7 @@ public void Dispose() { if (Array.Strings != IntPtr.Zero) { - NativeMethods.git_strarray_free(ref Array); + NativeMethods.git_strarray_dispose(ref Array); } // Now that we've freed the memory, zero out the structure. diff --git a/LibGit2Sharp/Core/NativeMethods.cs b/LibGit2Sharp/Core/NativeMethods.cs index 00b035457..dd33f5efb 100644 --- a/LibGit2Sharp/Core/NativeMethods.cs +++ b/LibGit2Sharp/Core/NativeMethods.cs @@ -14,6 +14,11 @@ // ReSharper disable InconsistentNaming namespace LibGit2Sharp.Core { + public static class NativeDllName + { + public const string Name = "git2"; + } + internal static class NativeMethods { public const uint GIT_PATH_MAX = 4096; @@ -252,34 +257,35 @@ internal static extern unsafe int git_blame_file( internal static extern unsafe void git_blame_free(git_blame* blame); [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] - internal static extern unsafe int git_blob_create_fromdisk( + internal static extern unsafe int git_blob_create_from_disk( ref GitOid id, git_repository* repo, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictFilePathMarshaler))] FilePath path); [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] - internal static extern unsafe int git_blob_create_fromworkdir( + internal static extern unsafe int git_blob_create_from_workdir( ref GitOid id, git_repository* repo, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictFilePathMarshaler))] FilePath relative_path); [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] - internal static extern unsafe int git_blob_create_fromstream( + internal static extern unsafe int git_blob_create_from_stream( out IntPtr stream, git_repository* repositoryPtr, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string hintpath); [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] - internal static extern int git_blob_create_fromstream_commit( + internal static extern int git_blob_create_from_stream_commit( ref GitOid oid, IntPtr stream); [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] - internal static extern unsafe int git_blob_filtered_content( + internal static extern unsafe int git_blob_filter( GitBuf buf, git_object* blob, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string as_path, - [MarshalAs(UnmanagedType.Bool)] bool check_for_binary_data); + git_blob_filter_options opts); + [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] internal static extern unsafe IntPtr git_blob_rawcontent(git_object* blob); @@ -638,7 +644,7 @@ internal static extern int git_config_next( // call StrictUtf8Marshaler.FromNative manually. See the discussion here: // http://social.msdn.microsoft.com/Forums/en-US/netfx64bit/thread/1eb746c6-d695-4632-8a9e-16c4fa98d481 [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - internal delegate int git_cred_acquire_cb( + internal delegate int git_credential_acquire_cb( out IntPtr cred, IntPtr url, IntPtr username_from_url, @@ -646,16 +652,16 @@ internal delegate int git_cred_acquire_cb( IntPtr payload); [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] - internal static extern int git_cred_default_new(out IntPtr cred); + internal static extern int git_credential_default_new(out IntPtr cred); [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] - internal static extern int git_cred_userpass_plaintext_new( + internal static extern int git_credential_userpass_plaintext_new( out IntPtr cred, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string username, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string password); [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] - internal static extern void git_cred_free(IntPtr cred); + internal static extern void git_credential_free(IntPtr cred); [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] internal static extern unsafe int git_describe_commit( @@ -1075,7 +1081,7 @@ internal static extern unsafe int git_note_foreach( internal static extern unsafe int git_odb_add_backend(git_odb* odb, IntPtr backend, int priority); [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] - internal static extern IntPtr git_odb_backend_malloc(IntPtr backend, UIntPtr len); + internal static extern IntPtr git_odb_backend_data_alloc(IntPtr backend, UIntPtr len); [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] internal static extern unsafe int git_odb_exists(git_odb* odb, ref GitOid id); @@ -1801,7 +1807,7 @@ internal static extern unsafe void git_status_list_free( git_status_list* statusList); [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] - internal static extern void git_strarray_free( + internal static extern void git_strarray_dispose( ref GitStrArray array); [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] diff --git a/LibGit2Sharp/Core/Proxy.cs b/LibGit2Sharp/Core/Proxy.cs index 86d632576..5cf4fab0c 100644 --- a/LibGit2Sharp/Core/Proxy.cs +++ b/LibGit2Sharp/Core/Proxy.cs @@ -36,34 +36,34 @@ public static unsafe BlameHandle git_blame_file( #region git_blob_ - public static unsafe IntPtr git_blob_create_fromstream(RepositoryHandle repo, string hintpath) + public static unsafe IntPtr git_blob_create_from_stream(RepositoryHandle repo, string hintpath) { IntPtr writestream_ptr; - Ensure.ZeroResult(NativeMethods.git_blob_create_fromstream(out writestream_ptr, repo, hintpath)); + Ensure.ZeroResult(NativeMethods.git_blob_create_from_stream(out writestream_ptr, repo, hintpath)); return writestream_ptr; } - public static unsafe ObjectId git_blob_create_fromstream_commit(IntPtr writestream_ptr) + public static unsafe ObjectId git_blob_create_from_stream_commit(IntPtr writestream_ptr) { var oid = new GitOid(); - Ensure.ZeroResult(NativeMethods.git_blob_create_fromstream_commit(ref oid, writestream_ptr)); + Ensure.ZeroResult(NativeMethods.git_blob_create_from_stream_commit(ref oid, writestream_ptr)); return oid; } - public static unsafe ObjectId git_blob_create_fromdisk(RepositoryHandle repo, FilePath path) + public static unsafe ObjectId git_blob_create_from_disk(RepositoryHandle repo, FilePath path) { var oid = new GitOid(); - int res = NativeMethods.git_blob_create_fromdisk(ref oid, repo, path); + int res = NativeMethods.git_blob_create_from_disk(ref oid, repo, path); Ensure.ZeroResult(res); return oid; } - public static unsafe ObjectId git_blob_create_fromfile(RepositoryHandle repo, FilePath path) + public static unsafe ObjectId git_blob_create_from_file(RepositoryHandle repo, FilePath path) { var oid = new GitOid(); - int res = NativeMethods.git_blob_create_fromworkdir(ref oid, repo, path); + int res = NativeMethods.git_blob_create_from_workdir(ref oid, repo, path); Ensure.ZeroResult(res); return oid; @@ -76,7 +76,14 @@ public static unsafe UnmanagedMemoryStream git_blob_filtered_content_stream(Repo return new RawContentStream(handle, h => { - Ensure.ZeroResult(NativeMethods.git_blob_filtered_content(buf, h, path, check_for_binary_data)); + var opts = new git_blob_filter_options(); + if (check_for_binary_data) + opts.flags = GitBlobOptionFlags.GIT_BLOB_FILTER_CHECK_FOR_BINARY; + else + opts.flags = GitBlobOptionFlags.GIT_BLOB_NONE; + + Ensure.ZeroResult(NativeMethods.git_blob_filter(buf, h, path, opts)); + return buf.ptr; }, h => (long)buf.size, @@ -664,11 +671,11 @@ public static unsafe IntPtr git_config_lock(git_config* config) #endregion - #region git_cred_ + #region git_credential_ - public static void git_cred_free(IntPtr cred) + public static void git_credential_free(IntPtr cred) { - NativeMethods.git_cred_free(cred); + NativeMethods.git_credential_free(cred); } #endregion @@ -1525,9 +1532,9 @@ public static unsafe void git_odb_add_backend(ObjectDatabaseHandle odb, IntPtr b Ensure.ZeroResult(NativeMethods.git_odb_add_backend(odb, backend, priority)); } - public static IntPtr git_odb_backend_malloc(IntPtr backend, UIntPtr len) + public static IntPtr git_odb_backend_data_alloc(IntPtr backend, UIntPtr len) { - IntPtr toReturn = NativeMethods.git_odb_backend_malloc(backend, len); + IntPtr toReturn = NativeMethods.git_odb_backend_data_alloc(backend, len); if (IntPtr.Zero == toReturn) { diff --git a/LibGit2Sharp/DefaultCredentials.cs b/LibGit2Sharp/DefaultCredentials.cs index b11b4f540..950c2064d 100644 --- a/LibGit2Sharp/DefaultCredentials.cs +++ b/LibGit2Sharp/DefaultCredentials.cs @@ -16,7 +16,7 @@ public sealed class DefaultCredentials : Credentials /// 0 for success, < 0 to indicate an error, > 0 to indicate no credential was acquired. protected internal override int GitCredentialHandler(out IntPtr cred) { - return NativeMethods.git_cred_default_new(out cred); + return NativeMethods.git_credential_default_new(out cred); } } } diff --git a/LibGit2Sharp/LibGit2Sharp.csproj b/LibGit2Sharp/LibGit2Sharp.csproj index b00432a27..dfdf52e34 100644 --- a/LibGit2Sharp/LibGit2Sharp.csproj +++ b/LibGit2Sharp/LibGit2Sharp.csproj @@ -1,7 +1,7 @@  - netstandard2.0;netcoreapp2.1 + net48 true LibGit2Sharp brings all the might and speed of libgit2, a native Git implementation, to the managed world of .Net and Mono. LibGit2Sharp contributors @@ -18,6 +18,8 @@ ..\libgit2sharp.snk square-logo.png App_Readme/LICENSE.md + true + AnyCPU;x64 @@ -32,9 +34,15 @@ - - - + + + + + + + + + diff --git a/LibGit2Sharp/ObjectDatabase.cs b/LibGit2Sharp/ObjectDatabase.cs index 3a4ebcdb6..82e1d0b12 100644 --- a/LibGit2Sharp/ObjectDatabase.cs +++ b/LibGit2Sharp/ObjectDatabase.cs @@ -104,8 +104,8 @@ public virtual Blob CreateBlob(string path) } ObjectId id = Path.IsPathRooted(path) - ? Proxy.git_blob_create_fromdisk(repo.Handle, path) - : Proxy.git_blob_create_fromfile(repo.Handle, path); + ? Proxy.git_blob_create_from_disk(repo.Handle, path) + : Proxy.git_blob_create_from_file(repo.Handle, path); return repo.Lookup(id); } @@ -277,7 +277,7 @@ private unsafe Blob CreateBlob(Stream stream, string hintpath, long? numberOfByt throw new ArgumentException("The stream cannot be read from.", "stream"); } - IntPtr writestream_ptr = Proxy.git_blob_create_fromstream(repo.Handle, hintpath); + IntPtr writestream_ptr = Proxy.git_blob_create_from_stream(repo.Handle, hintpath); GitWriteStream writestream = Marshal.PtrToStructure(writestream_ptr); try @@ -321,7 +321,7 @@ private unsafe Blob CreateBlob(Stream stream, string hintpath, long? numberOfByt throw e; } - ObjectId id = Proxy.git_blob_create_fromstream_commit(writestream_ptr); + ObjectId id = Proxy.git_blob_create_from_stream_commit(writestream_ptr); return repo.Lookup(id); } diff --git a/LibGit2Sharp/OdbBackend.cs b/LibGit2Sharp/OdbBackend.cs index 9736ed803..9acd5cf82 100644 --- a/LibGit2Sharp/OdbBackend.cs +++ b/LibGit2Sharp/OdbBackend.cs @@ -66,7 +66,7 @@ protected unsafe UnmanagedMemoryStream Allocate(long size) throw new ArgumentOutOfRangeException("size"); } - IntPtr buffer = Proxy.git_odb_backend_malloc(this.GitOdbBackendPointer, new UIntPtr((ulong)size)); + IntPtr buffer = Proxy.git_odb_backend_data_alloc(this.GitOdbBackendPointer, new UIntPtr((ulong)size)); return new UnmanagedMemoryStream((byte*)buffer, 0, size, FileAccess.ReadWrite); } diff --git a/LibGit2Sharp/RemoteCallbacks.cs b/LibGit2Sharp/RemoteCallbacks.cs index ce5dccf81..fe015915d 100644 --- a/LibGit2Sharp/RemoteCallbacks.cs +++ b/LibGit2Sharp/RemoteCallbacks.cs @@ -284,6 +284,27 @@ private int GitCredentialHandler( { types |= SupportedCredentialTypes.Default; } + if (credTypes.HasFlag(GitCredentialType.SshKey)) + { + types |= SupportedCredentialTypes.SshKey; + } + if (credTypes.HasFlag(GitCredentialType.SshMemory)) + { + types |= SupportedCredentialTypes.SshMemory; + } + if (credTypes.HasFlag(GitCredentialType.SshCustom)) + { + types |= SupportedCredentialTypes.SshCustom; + } + if (credTypes.HasFlag(GitCredentialType.SshInteractive)) + { + types |= SupportedCredentialTypes.SshInteractive; + } + if (credTypes.HasFlag(GitCredentialType.Username)) + { + types |= SupportedCredentialTypes.Username; + } + ptr = IntPtr.Zero; try diff --git a/LibGit2Sharp/SecureUsernamePasswordCredentials.cs b/LibGit2Sharp/SecureUsernamePasswordCredentials.cs index 16427ddf3..f34e93b62 100644 --- a/LibGit2Sharp/SecureUsernamePasswordCredentials.cs +++ b/LibGit2Sharp/SecureUsernamePasswordCredentials.cs @@ -28,7 +28,7 @@ protected internal override int GitCredentialHandler(out IntPtr cred) { passwordPtr = Marshal.SecureStringToGlobalAllocUnicode(Password); - return NativeMethods.git_cred_userpass_plaintext_new(out cred, Username, Marshal.PtrToStringUni(passwordPtr)); + return NativeMethods.git_credential_userpass_plaintext_new(out cred, Username, Marshal.PtrToStringUni(passwordPtr)); } finally { diff --git a/LibGit2Sharp/SshCredentials.cs b/LibGit2Sharp/SshCredentials.cs new file mode 100644 index 000000000..a448b71a7 --- /dev/null +++ b/LibGit2Sharp/SshCredentials.cs @@ -0,0 +1,144 @@ +using LibGit2Sharp.Core; +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; + +// Code from here: https://github.com/alex-weaver/libgit2sharp/commit/2ab9fdd14f43dd63c7e4406768d3d6799fb68bc4 + +namespace LibGit2Sharp.Ssh +{ + internal static class NativeMethods + { + private const string libgit2 = NativeDllName.Name; + + [DllImport(libgit2)] + internal static extern int git_credential_ssh_key_new( + out IntPtr cred, + [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string username, + [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string publickey, + [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string privatekey, + [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string passphrase); + + [DllImport(libgit2)] + internal static extern int git_credential_ssh_key_memory_new( + out IntPtr cred, + [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string username, + [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string publickey, + [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string privatekey, + [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string passphrase); + } + + /// + /// Class that holds SSH username with key credentials for remote repository access. + /// + public sealed class SshUserKeyCredentials : Credentials + { + /// + /// Callback to acquire a credential object. + /// + /// The newly created credential object. + /// 0 for success, < 0 to indicate an error, > 0 to indicate no credential was acquired. + internal protected override int GitCredentialHandler(out IntPtr cred) + { + if (Username == null) + { + throw new InvalidOperationException("SshUserKeyCredentials contains a null Username."); + } + + if (Passphrase == null) + { + throw new InvalidOperationException("SshUserKeyCredentials contains a null Passphrase."); + } + + if (PublicKey == null) + { + throw new InvalidOperationException("SshUserKeyCredentials contains a null PublicKey."); + } + + if (PrivateKey == null) + { + throw new InvalidOperationException("SshUserKeyCredentials contains a null PrivateKey."); + } + + return NativeMethods.git_credential_ssh_key_new(out cred, Username, PublicKey, PrivateKey, Passphrase); + } + + /// + /// Username for SSH authentication. + /// + public string Username { get; set; } + + /// + /// Public key file location for SSH authentication. + /// + public string PublicKey { get; set; } + + /// + /// Private key file location for SSH authentication. + /// + public string PrivateKey { get; set; } + + /// + /// Passphrase for SSH authentication. + /// + public string Passphrase { get; set; } + } + + /// + /// Class that holds SSH username with in-memory key credentials for remote repository access. + /// + public sealed class SshUserKeyMemoryCredentials : Credentials + { + /// + /// Callback to acquire a credential object. + /// + /// The newly created credential object. + /// 0 for success, < 0 to indicate an error, > 0 to indicate no credential was acquired. + internal protected override int GitCredentialHandler(out IntPtr cred) + { + if (Username == null) + { + throw new InvalidOperationException("SshUserKeyMemoryCredentials contains a null Username."); + } + + if (Passphrase == null) + { + throw new InvalidOperationException("SshUserKeyMemoryCredentials contains a null Passphrase."); + } + + if (PublicKey == null) + { + //throw new InvalidOperationException("SshUserKeyMemoryCredentials contains a null PublicKey."); + } + + if (PrivateKey == null) + { + throw new InvalidOperationException("SshUserKeyMemoryCredentials contains a null PrivateKey."); + } + + return NativeMethods.git_credential_ssh_key_memory_new(out cred, Username, PublicKey, PrivateKey, Passphrase); + } + + /// + /// Username for SSH authentication. + /// + public string Username { get; set; } + + /// + /// Public key for SSH authentication. + /// + public string PublicKey { get; set; } + + /// + /// Private key for SSH authentication. + /// + public string PrivateKey { get; set; } + + /// + /// Passphrase for SSH authentication. + /// + public string Passphrase { get; set; } + } + +} diff --git a/LibGit2Sharp/SupportedCredentialTypes.cs b/LibGit2Sharp/SupportedCredentialTypes.cs index bc38a259e..46b29d149 100644 --- a/LibGit2Sharp/SupportedCredentialTypes.cs +++ b/LibGit2Sharp/SupportedCredentialTypes.cs @@ -2,21 +2,51 @@ namespace LibGit2Sharp { - /// - /// Credential types supported by the server. If the server supports a particular type of - /// authentication, it will be set to true. - /// - [Flags] - public enum SupportedCredentialTypes - { - /// - /// Plain username and password combination - /// - UsernamePassword = (1 << 0), + /// + /// Credential types supported by the server. If the server supports a particular type of + /// authentication, it will be set to true. + /// + [Flags] + public enum SupportedCredentialTypes + { + /// + /// Plain username and password combination + /// + UsernamePassword = (1 << 0), - /// - /// Ask Windows to provide its default credentials for the current user (e.g. NTLM) - /// - Default = (1 << 1), - } + /// + /// SSH key-based authentication request + /// + SshKey = (1 << 1), + + /// + /// SSH key-based authentication request, with a custom signature + /// + SshCustom = (1 << 2), + + /// + /// Ask Windows to provide its default credentials for the current user (e.g. NTLM) + /// + Default = (1 << 3), + + /// + /// SSH interactive authentication request + /// + SshInteractive = (1 << 4), + + /// + /// Used as a pre-authentication step if the underlying transport + /// (eg. SSH, with no username in its URL) does not know which username + /// to use. + /// + Username = (1 << 5), + + /// + /// SSH key-based authentication request + /// Allows credentials to be read from memory instead of files. + /// Note that because of differences in crypto backend support, it might + /// not be functional. + /// + SshMemory = (1 << 6), + } } diff --git a/LibGit2Sharp/UsernamePasswordCredentials.cs b/LibGit2Sharp/UsernamePasswordCredentials.cs index 761be5c74..216749c67 100644 --- a/LibGit2Sharp/UsernamePasswordCredentials.cs +++ b/LibGit2Sharp/UsernamePasswordCredentials.cs @@ -22,7 +22,7 @@ protected internal override int GitCredentialHandler(out IntPtr cred) throw new InvalidOperationException("UsernamePasswordCredentials contains a null Username or Password."); } - return NativeMethods.git_cred_userpass_plaintext_new(out cred, Username, Password); + return NativeMethods.git_credential_userpass_plaintext_new(out cred, Username, Password); } static internal unsafe UsernamePasswordCredentials FromNative(GitCredentialUserpass* gitCred) diff --git a/NativeLibraryLoadTestApp/TestApp.cs b/NativeLibraryLoadTestApp/TestApp.cs index 234169a75..b0647436e 100644 --- a/NativeLibraryLoadTestApp/TestApp.cs +++ b/NativeLibraryLoadTestApp/TestApp.cs @@ -20,9 +20,16 @@ static int Main(string[] args) Console.Error.WriteLine("Usage: "); return -1; } - + var moduleName = args[0]; var loadFromDirectory = args[1]; + +/* + var moduleName = "git2"; + var loadFromDirectory = "C:\\Work\\Homegear\\ETS\\libgit2sharp-master\\bin\\LibGit2Sharp.Tests\\Release\\net48\\"; +*/ + + var expectedPath = Path.Combine(loadFromDirectory, (IntPtr.Size == 4) ? "x86" : "x64", moduleName + ".dll"); GlobalSettings.NativeLibraryPath = loadFromDirectory; @@ -34,7 +41,7 @@ static int Main(string[] args) int actualLength = GetModuleFileName(moduleHandle, buffer, capacity); var actualPath = buffer.ToString(0, actualLength); - if (expectedPath != actualPath) + if (!expectedPath.Equals(actualPath)) { Console.WriteLine(actualPath); return 1; diff --git a/NativeLibraryLoadTestApp/x64/NativeLibraryLoadTestApp.x64.csproj b/NativeLibraryLoadTestApp/x64/NativeLibraryLoadTestApp.x64.csproj index 3bca18b34..5ee022570 100644 --- a/NativeLibraryLoadTestApp/x64/NativeLibraryLoadTestApp.x64.csproj +++ b/NativeLibraryLoadTestApp/x64/NativeLibraryLoadTestApp.x64.csproj @@ -2,8 +2,9 @@ Exe - net472 + net48 x64 + AnyCPU;x64 diff --git a/NativeLibraryLoadTestApp/x86/NativeLibraryLoadTestApp.x86.csproj b/NativeLibraryLoadTestApp/x86/NativeLibraryLoadTestApp.x86.csproj index 0596f203c..e2176b12b 100644 --- a/NativeLibraryLoadTestApp/x86/NativeLibraryLoadTestApp.x86.csproj +++ b/NativeLibraryLoadTestApp/x86/NativeLibraryLoadTestApp.x86.csproj @@ -2,8 +2,9 @@ Exe - net472 + net48 x86 + AnyCPU;x64 diff --git a/Targets/CodeGenerator.targets b/Targets/CodeGenerator.targets index 249cd4f38..89f033282 100644 --- a/Targets/CodeGenerator.targets +++ b/Targets/CodeGenerator.targets @@ -41,7 +41,7 @@ - + @@ -57,7 +57,7 @@ { internal static class AssemblyCommitIds { - public const string LibGit2CommitSha = "$(libgit2_hash)"%3b + public const string LibGit2CommitSha = ""%3b public const string LibGit2SharpCommitSha = "$(LibGit2SharpCommitSha)"%3b } } diff --git a/Targets/GenerateNativeDllName.targets b/Targets/GenerateNativeDllName.targets index 244b707b4..346ee80a3 100644 --- a/Targets/GenerateNativeDllName.targets +++ b/Targets/GenerateNativeDllName.targets @@ -17,7 +17,7 @@ { internal static class NativeDllName { - public const string Name = "$(libgit2_filename)"%3b + public const string Name = "git2"%3b } } diff --git a/global.json b/global.json index 459551b1c..5ecd5ee6e 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "5.0.400" + "version": "5.0.301" } } From 08e6f125cc8aaef1f7a813b3efc185db171a98c6 Mon Sep 17 00:00:00 2001 From: Adrian Roman Date: Thu, 19 Aug 2021 14:35:28 +0300 Subject: [PATCH 2/4] Added some info about the changes in the fork in README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index c67e6ec8e..626ee51ac 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,11 @@ [libgit2]: http://libgit2.github.com/ +## Some info for this fork + +The changes are tested only for x64. +We added ssh support (basically the same as here: https://github.com/alex-weaver/libgit2sharp but also with some detailing in the SupportedCredentialTypes). libgit2 is not included anymore but it's based on libgit2-1.1.1. The dll should now be named simply git2.dll and it should be built with ssh support. This libgit2sharp fork uses the newer calls in libgit2, avoiding the deprecated ones, too. + ## Prerequisites - **Windows:** .NET 4.6.1+ From 45db8bc691efaf6c7197b47a2fe534d9a727d526 Mon Sep 17 00:00:00 2001 From: Adrian Roman Date: Fri, 20 Aug 2021 15:17:58 +0300 Subject: [PATCH 3/4] Added SshAgentCredentials class to expose git_credential_ssh_key_from_agent from libgit2 --- LibGit2Sharp/SshAgentCredentials.cs | 47 +++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 LibGit2Sharp/SshAgentCredentials.cs diff --git a/LibGit2Sharp/SshAgentCredentials.cs b/LibGit2Sharp/SshAgentCredentials.cs new file mode 100644 index 000000000..b7e9d1567 --- /dev/null +++ b/LibGit2Sharp/SshAgentCredentials.cs @@ -0,0 +1,47 @@ +using LibGit2Sharp.Core; +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; + +namespace LibGit2Sharp.Ssh +{ + + internal static class NativeMethodsAgent + { + private const string libgit2 = NativeDllName.Name; + + [DllImport(libgit2)] + internal static extern int git_credential_ssh_key_from_agent( + out IntPtr cred, + [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string username); + + } + + /// + /// Class that holds SSH username and gets credentials from agent for remote repository access. + /// + public sealed class SshAgentCredentials : Credentials + { + /// + /// Callback to acquire a credential object. + /// + /// The newly created credential object. + /// 0 for success, < 0 to indicate an error, > 0 to indicate no credential was acquired. + internal protected override int GitCredentialHandler(out IntPtr cred) + { + if (Username == null) + { + throw new InvalidOperationException("SshAgentCredentials contains a null Username."); + } + + return NativeMethodsAgent.git_credential_ssh_key_from_agent(out cred, Username); + } + + /// + /// Username for SSH authentication. + /// + public string Username { get; set; } + + } +} From 49ad1f0eb548c9f0d96de19c12d0b07db0842ffa Mon Sep 17 00:00:00 2001 From: Adrian Roman Date: Fri, 20 Aug 2021 15:25:29 +0300 Subject: [PATCH 4/4] Mentioned SshAgentCredentials class in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 626ee51ac..cc2168a18 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ ## Some info for this fork The changes are tested only for x64. -We added ssh support (basically the same as here: https://github.com/alex-weaver/libgit2sharp but also with some detailing in the SupportedCredentialTypes). libgit2 is not included anymore but it's based on libgit2-1.1.1. The dll should now be named simply git2.dll and it should be built with ssh support. This libgit2sharp fork uses the newer calls in libgit2, avoiding the deprecated ones, too. +We added ssh support (basically the same as here: https://github.com/alex-weaver/libgit2sharp but also with some detailing in the SupportedCredentialTypes and the SshAgentCredentials class). libgit2 is not included anymore but it's based on libgit2-1.1.1. The dll should now be named simply git2.dll and it should be built with ssh support. This libgit2sharp fork uses the newer calls in libgit2, avoiding the deprecated ones, too. ## Prerequisites