Skip to content

Commit beb2893

Browse files
authored
Merge pull request #397 from dotnet/bugfix/ref-realm
[WIP] Flow client and target names and realms separately
2 parents 72c3a92 + 01888e3 commit beb2893

25 files changed

+149
-65
lines changed

Kerberos.NET/Configuration/Krb5RealmConfig.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ public class Krb5RealmConfig : Krb5ConfigObject
350350
/// Compatibility shims should be enforced by the KDC.
351351
/// </summary>
352352
[EnumAsInteger]
353-
[DefaultValue(KerberosCompatibilityFlags.None)]
353+
[DefaultValue(KerberosCompatibilityFlags.IsolateRealmsConsistently)]
354354
[DisplayName("compatibility_flags")]
355355
public KerberosCompatibilityFlags CompatibilityFlags { get; set; }
356356
}

Kerberos.NET/Crypto/DecryptedKrbApReq.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ public override void Validate(ValidationActions validation)
186186

187187
if (validation.HasFlag(ValidationActions.Realm))
188188
{
189-
this.ValidateRealm(this.Ticket.CRealm, this.Authenticator.Realm);
189+
this.ValidateRealm(this.Ticket.CRealm, this.Authenticator.CRealm);
190190
}
191191

192192
var now = this.Now();

Kerberos.NET/Crypto/DecryptedKrbMessage.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
using System;
77
using Kerberos.NET.Entities;
8+
using Kerberos.NET.Server;
89
using static Kerberos.NET.Entities.KerberosConstants;
910

1011
namespace Kerberos.NET.Crypto
@@ -20,6 +21,8 @@ public Func<DateTimeOffset> Now
2021
set { this.nowFunc = value; }
2122
}
2223

24+
public KerberosCompatibilityFlags CompatibilityFlags { get; set; }
25+
2326
public abstract void Validate(ValidationActions validation);
2427

2528
public virtual void Decrypt(KeyTable keytab)

Kerberos.NET/Entities/Krb/KrbApReq.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ out KrbAuthenticator authenticator
5656
authenticator = new KrbAuthenticator
5757
{
5858
CName = tgsRep.CName,
59-
Realm = tgsRep.CRealm
59+
CRealm = tgsRep.CRealm
6060
};
6161

6262
if (rst.AuthenticatorChecksum != null)

Kerberos.NET/Entities/Krb/KrbAsRep.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ IRealmService realmService
4444
rst.RealmName = realmService.Name;
4545
}
4646

47+
if (string.IsNullOrWhiteSpace(rst.ClientRealmName))
48+
{
49+
rst.ClientRealmName = realmService.Name;
50+
}
51+
4752
KrbPrincipalName krbtgtName = KrbPrincipalName.WellKnown.Krbtgt(rst.RealmName);
4853

4954
if (rst.ServicePrincipal == null)
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
// -----------------------------------------------------------------------
1+
// -----------------------------------------------------------------------
22
// Licensed to The .NET Foundation under one or more agreements.
33
// The .NET Foundation licenses this file to you under the MIT license.
44
// -----------------------------------------------------------------------
55

6+
using System;
7+
68
namespace Kerberos.NET.Entities
79
{
810
public partial class KrbAuthenticator
@@ -11,5 +13,8 @@ public KrbAuthenticator()
1113
{
1214
this.AuthenticatorVersionNumber = 5;
1315
}
16+
17+
[Obsolete("Use to property named to match the spec `CRealm`.")]
18+
public string Realm { get => this.CRealm; set => this.CRealm = value; }
1419
}
15-
}
20+
}

Kerberos.NET/Entities/Krb/KrbAuthenticator.generated.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public partial class KrbAuthenticator
3333

3434
public int AuthenticatorVersionNumber { get; set; }
3535

36-
public string Realm { get; set; }
36+
public string CRealm { get; set; }
3737

3838
public KrbPrincipalName CName { get; set; }
3939

@@ -63,7 +63,7 @@ internal void Encode(AsnWriter writer, Asn1Tag tag)
6363
writer.WriteInteger(AuthenticatorVersionNumber);
6464
writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
6565
writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 1));
66-
writer.WriteCharacterString(UniversalTagNumber.GeneralString, Realm);
66+
writer.WriteCharacterString(UniversalTagNumber.GeneralString, CRealm);
6767
writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 1));
6868
writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 2));
6969
CName?.Encode(writer);
@@ -223,7 +223,7 @@ internal static void Decode<T>(AsnReader reader, Asn1Tag expectedTag, out T deco
223223
explicitReader.ThrowIfNotEmpty();
224224

225225
explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1));
226-
decoded.Realm = explicitReader.ReadCharacterString(UniversalTagNumber.GeneralString);
226+
decoded.CRealm = explicitReader.ReadCharacterString(UniversalTagNumber.GeneralString);
227227

228228
explicitReader.ThrowIfNotEmpty();
229229

Kerberos.NET/Entities/Krb/KrbAuthenticator.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
}-->
1919

2020
<asn:Integer name="AuthenticatorVersionNumber" explicitTag="0" backingType="int" />
21-
<asn:GeneralString name="Realm" explicitTag="1" />
21+
<asn:GeneralString name="CRealm" explicitTag="1" />
2222
<asn:AsnType name="CName" typeName="KrbPrincipalName" explicitTag="2" />
2323
<asn:AsnType name="Checksum" typeName="KrbChecksum" explicitTag="3" optional="true" />
2424
<asn:Integer name="CuSec" explicitTag="4" backingType="int" />

Kerberos.NET/Entities/Krb/KrbKdcRep.cs

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public static KrbCred GenerateWrappedServiceTicket(
2626
ServiceTicketRequest request,
2727
KrbEncryptionKey sessionKey = null,
2828
IEnumerable<KrbAuthorizationData> authz = null
29-
)
29+
)
3030
{
3131
GenerateServiceTicket<KrbTgsRep>(
3232
request,
@@ -46,8 +46,7 @@ public static T GenerateServiceTicket<T>(
4646
ServiceTicketRequest request,
4747
KrbEncryptionKey encryptionKey = null,
4848
IEnumerable<KrbAuthorizationData> authz = null
49-
)
50-
where T : KrbKdcRep, new()
49+
) where T : KrbKdcRep, new()
5150
{
5251
if (request.EncryptedPartKey == null)
5352
{
@@ -67,8 +66,14 @@ out MessageType messageType
6766

6867
var rep = new T
6968
{
70-
CName = encTicketPart.CName,
71-
CRealm = request.RealmName,
69+
CName = request.Compatibility.HasFlag(KerberosCompatibilityFlags.IsolateRealmsConsistently) ?
70+
KrbPrincipalName.FromPrincipal(request.Principal) ?? encTicketPart.CName :
71+
encTicketPart.CName,
72+
73+
CRealm = request.Compatibility.HasFlag(KerberosCompatibilityFlags.IsolateRealmsConsistently) ?
74+
request.ClientRealmName :
75+
request.RealmName,
76+
7277
MessageType = messageType,
7378
Ticket = ticket,
7479
EncPart = KrbEncryptedData.Encrypt(
@@ -91,8 +96,7 @@ private static ServiceTicketRequest GenerateServiceTicket<T>(
9196
out KrbEncKdcRepPart encKdcRepPart,
9297
out KeyUsage keyUsage,
9398
out MessageType messageType
94-
)
95-
where T : KrbKdcRep, new()
99+
) where T : KrbKdcRep, new()
96100
{
97101
if (request.Principal == null)
98102
{
@@ -112,17 +116,12 @@ out MessageType messageType
112116
if (request.Compatibility.HasFlag(KerberosCompatibilityFlags.NormalizeRealmsUppercase))
113117
{
114118
request.RealmName = request.RealmName?.ToUpperInvariant();
119+
request.ClientRealmName = request.ClientRealmName?.ToUpperInvariant() ?? throw new InvalidOperationException("Unknown client realm name");
115120
}
116121

117-
if (authz == null)
118-
{
119-
authz = GenerateAuthorizationData(request);
120-
}
122+
authz ??= GenerateAuthorizationData(request);
121123

122-
if (sessionKey == null)
123-
{
124-
sessionKey = KrbEncryptionKey.Generate(request.PreferredClientEType ?? request.ServicePrincipalKey.EncryptionType);
125-
}
124+
sessionKey ??= KrbEncryptionKey.Generate(request.PreferredClientEType ?? request.ServicePrincipalKey.EncryptionType);
126125

127126
encTicketPart = CreateEncTicketPart(request, authz.ToArray(), sessionKey);
128127
bool appendRealm = false;
@@ -146,6 +145,7 @@ out MessageType messageType
146145
KeyUsage.Ticket
147146
)
148147
};
148+
149149
if (typeof(T) == typeof(KrbAsRep))
150150
{
151151
encKdcRepPart = new KrbEncAsRepPart();
@@ -186,13 +186,15 @@ out MessageType messageType
186186
}
187187
}
188188
};
189+
189190
return request;
190191
}
191192

192193
private static KrbEncTicketPart CreateEncTicketPart(
193194
ServiceTicketRequest request,
194195
KrbAuthorizationData[] authorizationDatas,
195-
KrbEncryptionKey sessionKey)
196+
KrbEncryptionKey sessionKey
197+
)
196198
{
197199
var cname = CreateCNameForTicket(request);
198200

@@ -205,19 +207,16 @@ private static KrbEncTicketPart CreateEncTicketPart(
205207

206208
var addresses = request.Addresses;
207209

208-
if (addresses == null)
209-
{
210-
addresses = Array.Empty<KrbHostAddress>();
211-
}
210+
addresses ??= Array.Empty<KrbHostAddress>();
212211

213212
var encTicketPart = new KrbEncTicketPart()
214213
{
215214
CName = cname,
215+
CRealm = request.ClientRealmName,
216216
Key = sessionKey,
217217
AuthTime = request.Now,
218218
StartTime = request.StartTime,
219219
EndTime = request.EndTime,
220-
CRealm = request.RealmName,
221220
Flags = flags,
222221
AuthorizationData = authorizationDatas,
223222
CAddr = addresses.ToArray(),
@@ -238,7 +237,12 @@ private static KrbPrincipalName CreateCNameForTicket(ServiceTicketRequest reques
238237
{
239238
if (string.IsNullOrEmpty(request.SamAccountName))
240239
{
241-
return KrbPrincipalName.FromPrincipal(request.Principal, realm: request.RealmName);
240+
return KrbPrincipalName.FromPrincipal(
241+
request.Principal,
242+
realm: request.Compatibility.HasFlag(KerberosCompatibilityFlags.IsolateRealmsConsistently) ?
243+
request.ClientRealmName :
244+
request.RealmName
245+
);
242246
}
243247

244248
return new KrbPrincipalName

Kerberos.NET/Entities/Krb/KrbTgsReq.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ private static KrbApReq CreateApReq(KrbKdcRep kdcRep, KrbEncryptionKey tgtSessio
207207
var authenticator = new KrbAuthenticator
208208
{
209209
CName = kdcRep.CName,
210-
Realm = kdcRep.CRealm,
210+
CRealm = kdcRep.CRealm,
211211
SequenceNumber = GetNonce(),
212212
Checksum = checksum
213213
};

0 commit comments

Comments
 (0)