Skip to content

Commit

Permalink
ManagedHttpSmartSubtransport: provide certificate callbacks
Browse files Browse the repository at this point in the history
Provide certificate callback functionality when using the managed HTTP
smart subtransport.
  • Loading branch information
ethomson committed Feb 18, 2020
1 parent dc22039 commit 4381f70
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 7 deletions.
6 changes: 5 additions & 1 deletion LibGit2Sharp/CertificateX509.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ namespace LibGit2Sharp
/// </summary>
public class CertificateX509 : Certificate
{

/// <summary>
/// For mocking purposes
/// </summary>
Expand All @@ -30,6 +29,11 @@ internal unsafe CertificateX509(git_certificate_x509* cert)
Certificate = new X509Certificate(data);
}

internal CertificateX509(X509Certificate cert)
{
Certificate = cert;
}

internal unsafe IntPtr ToPointers(out IntPtr dataPtr)
{
var certData = Certificate.Export(X509ContentType.Cert);
Expand Down
32 changes: 27 additions & 5 deletions LibGit2Sharp/Core/ManagedHttpSmartSubtransport.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

namespace LibGit2Sharp.Core
{
Expand Down Expand Up @@ -50,12 +52,12 @@ private class ManagedHttpSmartSubtransportStream : SmartSubtransportStream
public ManagedHttpSmartSubtransportStream(ManagedHttpSmartSubtransport parent, string endpointUrl, bool isPost, string contentType)
: base(parent)
{
EndpointUrl = endpointUrl;
EndpointUrl = new Uri(endpointUrl);
IsPost = isPost;
ContentType = contentType;
}

private string EndpointUrl
private Uri EndpointUrl
{
get;
set;
Expand Down Expand Up @@ -100,14 +102,23 @@ public override int Write(Stream dataStream, long length)
return 0;
}

private static HttpWebRequest CreateWebRequest(string endpointUrl, bool isPost, string contentType)
private bool CertificateValidationProxy(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors errors)
{
int ret = SmartTransport.CertificateCheck(new CertificateX509(cert), (errors == SslPolicyErrors.None), EndpointUrl.Host);
Ensure.ZeroResult(ret);

return true;
}

private HttpWebRequest CreateWebRequest(Uri endpointUrl, bool isPost, string contentType)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create(endpointUrl);
webRequest.UserAgent = "git/1.0 (libgit2 custom transport)";
webRequest.ServicePoint.Expect100Continue = false;
webRequest.AllowAutoRedirect = false;
webRequest.ServerCertificateValidationCallback += CertificateValidationProxy;

if (isPost)
{
Expand Down Expand Up @@ -147,7 +158,18 @@ private HttpWebResponse GetResponseWithRedirects()
}
catch (WebException ex)
{
response = (HttpWebResponse)ex.Response;
if (ex.Response != null)
{
response = (HttpWebResponse)ex.Response;
}
else if (ex.InnerException != null)
{
throw ex.InnerException;
}
else
{
throw new Exception("unknown network failure");
}
}

if (response.StatusCode == HttpStatusCode.OK)
Expand All @@ -171,7 +193,7 @@ private HttpWebResponse GetResponseWithRedirects()
}
else if (response.StatusCode == HttpStatusCode.Moved || response.StatusCode == HttpStatusCode.Redirect)
{
request = CreateWebRequest(response.Headers["Location"], IsPost, ContentType);
request = CreateWebRequest(new Uri(response.Headers["Location"]), IsPost, ContentType);
continue;
}

Expand Down
8 changes: 7 additions & 1 deletion LibGit2Sharp/SmartSubtransportStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ private unsafe static int Read(
UIntPtr buf_size,
out UIntPtr bytes_read)
{
GitErrorCode errorCode = GitErrorCode.Error;
bytes_read = UIntPtr.Zero;

SmartSubtransportStream transportStream =
Expand All @@ -124,14 +125,19 @@ private unsafe static int Read(

return toReturn;
}
catch (NativeException ex)
{
errorCode = ex.ErrorCode;
Proxy.giterr_set_str(GitErrorCategory.Net, ex);
}
catch (Exception ex)
{
Proxy.git_error_set_str(GitErrorCategory.Net, ex);
}
}
}

return (int)GitErrorCode.Error;
return (int)errorCode;
}

private static unsafe int Write(IntPtr stream, IntPtr buffer, UIntPtr len)
Expand Down

0 comments on commit 4381f70

Please sign in to comment.