Skip to content

Commit fdb9231

Browse files
author
Tomas Urbonaitis
committed
Various code review fixes
1 parent 05b0ce1 commit fdb9231

8 files changed

Lines changed: 62 additions & 48 deletions

File tree

GVFS/GVFS.Common/Git/GitAuthentication.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,6 @@ public GitAuthentication(GitProcess git, string repoUrl)
3333
{
3434
this.GitSsl = new GitSsl(configSettings);
3535
}
36-
else
37-
{
38-
this.GitSsl = new GitSsl();
39-
}
4036
}
4137

4238
public bool IsBackingOff
@@ -166,12 +162,12 @@ public bool TryInitializeAndRequireAuth(ITracer tracer, out string errorMessage)
166162
return false;
167163
}
168164

169-
public void SetupSslIfNeeded(ITracer tracer, HttpClientHandler httpClientHandler, GitProcess gitProcess)
165+
public void ConfigureHttpClientHandlerSslIfNeeded(ITracer tracer, HttpClientHandler httpClientHandler, GitProcess gitProcess)
170166
{
171-
X509Certificate2 cert = this.GitSsl.GetCertificate(tracer, gitProcess);
167+
X509Certificate2 cert = this.GitSsl?.GetCertificate(tracer, gitProcess);
172168
if (cert != null)
173169
{
174-
if (!this.GitSsl.ShouldVerify)
170+
if (this.GitSsl != null && !this.GitSsl.ShouldVerify)
175171
{
176172
httpClientHandler.ServerCertificateCustomValidationCallback =
177173
(httpRequestMessage, c, cetChain, policyErrors) =>

GVFS/GVFS.Common/Git/GitConfigSetting.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ public class GitConfigSetting
99
public const string CredentialUseHttpPath = "credential.useHttpPath";
1010

1111
public const string HttpSslCert = "http.sslcert";
12-
public const string HttpSslKey = "http.sslkey";
1312
public const string HttpSslVerify = "http.sslverify";
1413
public const string HttpSslCertPasswordProtected = "http.sslcertpasswordprotected";
1514

GVFS/GVFS.Common/Git/GitSsl.cs

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ public class GitSsl
1717
public GitSsl()
1818
{
1919
this.certificatePathOrSubjectCommonName = null;
20+
2021
this.isCertificatePasswordProtected = false;
22+
23+
// True by default, both to have good default security settings and to match git behavior.
24+
// https://git-scm.com/docs/git-config#git-config-httpsslVerify
2125
this.ShouldVerify = true;
2226
}
2327

@@ -27,32 +31,26 @@ public GitSsl(IDictionary<string, GitConfigSetting> configSettings) : this()
2731
{
2832
if (configSettings.TryGetValue(GitConfigSetting.HttpSslCert, out GitConfigSetting sslCerts))
2933
{
30-
this.certificatePathOrSubjectCommonName = sslCerts.Values.Single();
34+
this.certificatePathOrSubjectCommonName = sslCerts.Values.Last();
3135
}
3236

3337
if (configSettings.TryGetValue(GitConfigSetting.HttpSslCertPasswordProtected, out GitConfigSetting isSslCertPasswordProtected))
3438
{
35-
this.isCertificatePasswordProtected = isSslCertPasswordProtected.Values.Select(bool.Parse).Single();
39+
this.isCertificatePasswordProtected = isSslCertPasswordProtected.Values.Select(bool.Parse).Last();
3640
}
3741

3842
if (configSettings.TryGetValue(GitConfigSetting.HttpSslVerify, out GitConfigSetting sslVerify))
3943
{
40-
this.ShouldVerify = sslVerify.Values.Select(bool.Parse).Single();
44+
this.ShouldVerify = sslVerify.Values.Select(bool.Parse).Last();
4145
}
4246
}
4347
}
44-
45-
public bool ShouldVerify { get; }
46-
47-
public string GetCertificatePassword(ITracer tracer, GitProcess git)
48-
{
49-
if (git.TryGetCertificatePassword(tracer, this.certificatePathOrSubjectCommonName, out string password, out string error))
50-
{
51-
return password;
52-
}
5348

54-
return null;
55-
}
49+
/// <summary>
50+
/// Gets a value indicating whether SSL certificates being loaded should be verified. Also used to determine, whether client should verify server SSL certificate. True by default.
51+
/// </summary>
52+
/// <value><c>true</c> if should verify SSL certificates; otherwise, <c>false</c>.</value>
53+
public bool ShouldVerify { get; }
5654

5755
public X509Certificate2 GetCertificate(ITracer tracer, GitProcess gitProcess)
5856
{
@@ -74,33 +72,28 @@ public X509Certificate2 GetCertificate(ITracer tracer, GitProcess gitProcess)
7472

7573
if (result == null)
7674
{
77-
tracer.RelatedError("Certificate {0} not found", this.certificatePathOrSubjectCommonName);
75+
tracer.RelatedError(metadata, $"Certificate {this.certificatePathOrSubjectCommonName} not found");
7876
}
7977

8078
return result;
8179
}
8280

8381
private static void LogWithAppropriateLevel(ITracer tracer, EventMetadata metadata, IEnumerable<X509Certificate2> certificates, string logMessage)
8482
{
85-
Action<EventMetadata, string> loggingFunction;
8683
int numberOfCertificates = certificates.Count();
8784

8885
switch (numberOfCertificates)
8986
{
9087
case 0:
91-
loggingFunction = tracer.RelatedError;
88+
tracer.RelatedError(metadata, logMessage);
9289
break;
9390
case 1:
94-
loggingFunction = tracer.RelatedInfo;
91+
tracer.RelatedInfo(metadata, logMessage);
9592
break;
9693
default:
97-
loggingFunction = tracer.RelatedWarning;
94+
tracer.RelatedWarning(metadata, logMessage);
9895
break;
9996
}
100-
101-
loggingFunction(
102-
metadata,
103-
logMessage);
10497
}
10598

10699
private static string GetSubjectNameLineForLogging(IEnumerable<X509Certificate2> certificates)
@@ -110,6 +103,16 @@ private static string GetSubjectNameLineForLogging(IEnumerable<X509Certificate2>
110103
certificates.Select(x => x.Subject));
111104
}
112105

106+
private string GetCertificatePassword(ITracer tracer, GitProcess git)
107+
{
108+
if (git.TryGetCertificatePassword(tracer, this.certificatePathOrSubjectCommonName, out string password, out string error))
109+
{
110+
return password;
111+
}
112+
113+
return null;
114+
}
115+
113116
private X509Certificate2 GetCertificateFromFile(ITracer tracer, EventMetadata metadata, GitProcess gitProcess)
114117
{
115118
string certificatePassword = null;
@@ -120,10 +123,7 @@ private X509Certificate2 GetCertificateFromFile(ITracer tracer, EventMetadata me
120123
if (string.IsNullOrEmpty(certificatePassword))
121124
{
122125
tracer.RelatedWarning(
123-
new EventMetadata
124-
{
125-
{ "SslCertificate", this.certificatePathOrSubjectCommonName }
126-
},
126+
metadata,
127127
"Git config indicates, that certificate is password protected, but retrieved password was null or empty!");
128128
}
129129

@@ -145,7 +145,7 @@ private X509Certificate2 GetCertificateFromFile(ITracer tracer, EventMetadata me
145145
}
146146
catch (CryptographicException cryptEx)
147147
{
148-
metadata.Add("Exception", cryptEx);
148+
metadata.Add("Exception", cryptEx.ToString());
149149
tracer.RelatedError(metadata, "Error, while loading certificate from disk");
150150
return null;
151151
}

GVFS/GVFS.Common/Http/ConfigHttpRequestor.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,15 @@ public bool TryQueryGVFSConfig(bool logErrors, out ServerGVFSConfig serverGVFSCo
8888
httpStatus = httpException.StatusCode;
8989
}
9090

91-
this.Tracer.RelatedError(
92-
new EventMetadata
93-
{
94-
{ "Exception", output.Error }
95-
},
96-
"TryQueryGVFSConfig failed");
91+
if (logErrors)
92+
{
93+
this.Tracer.RelatedError(
94+
new EventMetadata
95+
{
96+
{ "Exception", output.Error.ToString() }
97+
},
98+
$"{nameof(this.TryQueryGVFSConfig)} failed");
99+
}
97100

98101
return false;
99102
}

GVFS/GVFS.Common/Http/HttpRequestor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ protected HttpRequestor(ITracer tracer, RetryConfig retryConfig, Enlistment enli
4242

4343
HttpClientHandler httpClientHandler = new HttpClientHandler() { UseDefaultCredentials = true };
4444

45-
this.authentication.SetupSslIfNeeded(this.Tracer, httpClientHandler, enlistment.CreateGitProcess());
45+
this.authentication.ConfigureHttpClientHandlerSslIfNeeded(this.Tracer, httpClientHandler, enlistment.CreateGitProcess());
4646

4747
this.client = new HttpClient(httpClientHandler)
4848
{

GVFS/GVFS.UnitTests/Common/GitConfigHelperTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public void ParseKeyValuesTest()
106106
[TestCase]
107107
public void ParseSpaceSeparatedKeyValuesTest()
108108
{
109-
string input = @"
109+
string input = @"
110110
core.gvfs true
111111
gc.auto 0
112112
section.key value1
@@ -116,7 +116,7 @@ section.key value4
116116
section.KEY value5" +
117117
"\nsection.empty ";
118118

119-
Dictionary<string, GitConfigSetting> result = GitConfigHelper.ParseKeyValues(input, ' ');
119+
Dictionary<string, GitConfigSetting> result = GitConfigHelper.ParseKeyValues(input, ' ');
120120

121121
result.Count.ShouldEqual(4);
122122
result["core.gvfs"].Values.Single().ShouldEqual("true");

GVFS/GVFS.UnitTests/Git/GitAuthenticationTests.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
using GVFS.Common.Git;
2+
using GVFS.Tests;
23
using GVFS.Tests.Should;
34
using GVFS.UnitTests.Mock.Common;
45
using GVFS.UnitTests.Mock.Git;
56
using NUnit.Framework;
67

78
namespace GVFS.UnitTests.Git
89
{
9-
[TestFixture]
10+
[TestFixtureSource(typeof(DataSources), nameof(DataSources.AllBools))]
1011
public class GitAuthenticationTests
1112
{
1213
private const string CertificatePath = "certificatePath";
1314

15+
private readonly bool sslSettingsPresent;
16+
17+
public GitAuthenticationTests(bool sslSettingsPresent)
18+
{
19+
this.sslSettingsPresent = sslSettingsPresent;
20+
}
21+
1422
[TestCase]
1523
public void AuthShouldBackoffAfterFirstRetryFailure()
1624
{
@@ -175,7 +183,15 @@ private MockGitProcess GetGitProcess()
175183
MockGitProcess gitProcess = new MockGitProcess();
176184
gitProcess.SetExpectedCommandResult("config gvfs.FunctionalTests.UserName", () => new GitProcess.Result(string.Empty, string.Empty, GitProcess.Result.GenericFailureCode));
177185
gitProcess.SetExpectedCommandResult("config gvfs.FunctionalTests.Password", () => new GitProcess.Result(string.Empty, string.Empty, GitProcess.Result.GenericFailureCode));
178-
gitProcess.SetExpectedCommandResult("config --get-urlmatch http mock://repoUrl", () => new GitProcess.Result($"http.sslCert {CertificatePath}\nhttp.sslCertPasswordProtected true\n\n", string.Empty, GitProcess.Result.SuccessCode));
186+
187+
if (this.sslSettingsPresent)
188+
{
189+
gitProcess.SetExpectedCommandResult("config --get-urlmatch http mock://repoUrl", () => new GitProcess.Result($"http.sslCert {CertificatePath}\nhttp.sslCertPasswordProtected true\n\n", string.Empty, GitProcess.Result.SuccessCode));
190+
}
191+
else
192+
{
193+
gitProcess.SetExpectedCommandResult("config --get-urlmatch http mock://repoUrl", () => new GitProcess.Result(string.Empty, string.Empty, GitProcess.Result.SuccessCode));
194+
}
179195

180196
int revocations = 0;
181197
gitProcess.SetExpectedCommandResult(

GVFS/GVFS.UnitTests/Mock/Common/MockTracer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public void RelatedInfo(string message)
5353
public void RelatedInfo(EventMetadata metadata, string message)
5454
{
5555
metadata[TracingConstants.MessageKey.InfoMessage] = message;
56-
this.RelatedWarningEvents.Add(JsonConvert.SerializeObject(metadata));
56+
this.RelatedInfoEvents.Add(JsonConvert.SerializeObject(metadata));
5757
}
5858

5959
public void RelatedInfo(string format, params object[] args)

0 commit comments

Comments
 (0)