Skip to content

Commit 9b216c7

Browse files
authored
Merge branch 'master' into master
2 parents e415733 + 4618d20 commit 9b216c7

5 files changed

Lines changed: 75 additions & 3 deletions

File tree

.github/workflows/codeql.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: "CodeQL - C#"
2+
3+
on:
4+
push:
5+
branches: [master, main]
6+
pull_request:
7+
branches: [master, main]
8+
schedule:
9+
- cron: '0 4 * * 0' # Runs every Sunday at 4AM
10+
11+
jobs:
12+
analyze:
13+
name: CodeQL Security Scan
14+
runs-on: windows-latest
15+
16+
permissions:
17+
actions: read
18+
contents: read
19+
security-events: write
20+
21+
steps:
22+
- name: Checkout repository
23+
uses: actions/checkout@v4
24+
25+
- name: Setup .NET
26+
uses: actions/setup-dotnet@v4
27+
with:
28+
dotnet-version: '9.x'
29+
30+
- name: Restore dependencies
31+
run: dotnet restore RestSharp.Authenticators.Digest.sln
32+
33+
- name: Initialize CodeQL
34+
uses: github/codeql-action/init@v3
35+
with:
36+
languages: csharp
37+
38+
- name: Build project
39+
run: dotnet build RestSharp.Authenticators.Digest.sln --no-restore --configuration Release
40+
41+
- name: Run CodeQL analysis
42+
uses: github/codeql-action/analyze@v3

RestSharp.Authenticators.Digest.sln

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "images", "images", "{AB3531
2525
images\icon.png = images\icon.png
2626
EndProjectSection
2727
EndProject
28+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{E1BF084D-B1BB-4A98-9B19-55A78DD0CBB9}"
29+
EndProject
30+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{46506451-F83B-4074-9BF7-D05E3CBB7D05}"
31+
ProjectSection(SolutionItems) = preProject
32+
.github\workflows\codeql.yml = .github\workflows\codeql.yml
33+
EndProjectSection
34+
EndProject
2835
Global
2936
GlobalSection(SolutionConfigurationPlatforms) = preSolution
3037
Debug|Any CPU = Debug|Any CPU
@@ -66,6 +73,7 @@ Global
6673
GlobalSection(NestedProjects) = preSolution
6774
{CBC300D5-B57C-4588-BE2D-26AFF9D102F9} = {1D1F223D-4333-4699-BB10-8E1111DD0D75}
6875
{607B2AF3-A2CB-47D3-AA26-B8E79E93A4EE} = {EB4DC82C-C9F5-4745-82A9-D1287A1BBC3F}
76+
{46506451-F83B-4074-9BF7-D05E3CBB7D05} = {E1BF084D-B1BB-4A98-9B19-55A78DD0CBB9}
6977
EndGlobalSection
7078
GlobalSection(ExtensibilityGlobals) = postSolution
7179
SolutionGuid = {CFB144EC-8162-4D4F-A173-0E97D11BD3D8}

src/DigestAuthenticator/DigestAuthenticator.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,6 @@
4747
</ItemGroup>
4848
<ItemGroup>
4949
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="3.1.32" />
50-
<PackageReference Include="RestSharp" Version="111.2.0" />
50+
<PackageReference Include="RestSharp" Version="112.0.0" />
5151
</ItemGroup>
5252
</Project>

src/DigestAuthenticator/DigestAuthenticatorManager.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ internal class DigestAuthenticatorManager
4949
private string? _realm;
5050

5151
private readonly RestClientOptions? _handshakeClientOptions;
52+
/// <summary>
53+
/// The opaque that is returned by the first digest request (without the data).
54+
/// </summary>
55+
private string? _opaque;
5256

5357
static DigestAuthenticatorManager()
5458
{
@@ -142,6 +146,7 @@ public string GetDigestHeader(string digestUri, Method method)
142146
$"uri=\"{digestUri}\"," +
143147
"algorithm=MD5," +
144148
$"response=\"{digestResponse}\"," +
149+
(!string.IsNullOrWhiteSpace(_opaque) ? $"opaque=\"{_opaque}\"," : string.Empty) +
145150
$"qop={_qop}," +
146151
$"nc={DigestHeader.NONCE_COUNT:00000000}," +
147152
$"cnonce=\"{_cnonce}\"";
@@ -196,5 +201,14 @@ private void GetDigestDataFromFailResponse(RestResponse response)
196201
_realm = digestHeader.Realm;
197202
_nonce = digestHeader.Nonce;
198203
_qop = digestHeader.Qop;
204+
if (!string.IsNullOrWhiteSpace(_qop) && _qop!.Contains(','))
205+
{
206+
_qop = _qop!
207+
.Split(',')
208+
.Select(q => q.Trim())
209+
.FirstOrDefault(q => q.Equals("auth", StringComparison.OrdinalIgnoreCase)) // prefer "auth" if the server offered several
210+
?? _qop.Split(',')[0].Trim();
211+
}
212+
_opaque = digestHeader.Opaque;
199213
}
200214
}

src/DigestAuthenticator/DigestHeader.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ internal class DigestHeader
1414

1515
public const string REALM = "realm";
1616

17+
public const string OPAQUE = "opaque";
18+
1719
public const string REGEX_PATTERN =
1820
"realm=\"(?<realm>.*?)\"|qop=(?:\"(?<qop>.*?)\"|(?<qop>[^\",\\s]+))|nonce=\"(?<nonce>.*?)\"|stale=\"(?<stale>.*?)\"|opaque=\"(?<opaque>.*?)\"|domain=\"(?<domain>.*?)\"";
19-
21+
2022
private static readonly Regex _regex;
2123

2224
static DigestHeader()
@@ -50,6 +52,11 @@ public DigestHeader(string authenticateHeader, ILogger logger)
5052
{
5153
Nonce = m.Groups[NONCE].Value;
5254
}
55+
56+
if (m.Groups[OPAQUE].Success)
57+
{
58+
Opaque = m.Groups[OPAQUE].Value;
59+
}
5360
}
5461

5562
if (AllDataCorrectFilled())
@@ -65,10 +72,11 @@ public DigestHeader(string authenticateHeader, ILogger logger)
6572
public string? Nonce { get; }
6673
public string? Qop { get; }
6774
public string? Realm { get; }
75+
public string? Opaque { get; }
6876

6977
public override string ToString()
7078
{
71-
return $"{nameof(Realm)}=\"{Realm}\"&{nameof(Nonce)}=\"{Nonce}\"&{nameof(Qop)}=\"{Qop}\"";
79+
return $"{nameof(Realm)}=\"{Realm}\"&{nameof(Nonce)}=\"{Nonce}\"&{nameof(Qop)}=\"{Qop}\"&{nameof(Opaque)}=\"{Opaque}\"";
7280
}
7381

7482
private bool AllDataCorrectFilled()

0 commit comments

Comments
 (0)