private KerberosApRequest CreateApRequest(APOptions option, KerberosTicket ticket, EncryptionKey subKey, AuthorizationData data, KeyUsageNumber keyUsageNumber, ChecksumType checksumType, byte[] checksumBody) { Authenticator authenticator = CreateAuthenticator(ticket, data, subKey, checksumType, checksumBody); KerberosApRequest apRequest = new KerberosApRequest(Context.Pvno, option, ticket, authenticator, keyUsageNumber); return(apRequest); }
/// <summary> /// Create context /// </summary> /// <param name="domain">Domain name</param> /// <param name="cName">Principal name</param> /// <param name="password">Password of principal</param> /// <param name="accountType">Accoundtype, user or device</param> /// <param name="armorTicket">Computer TGT as armor ticket</param> /// <param name="armorSessionKey">Computer TGS session key as armor session key</param> public KerberosContext(string domain, string cName, string password, KerberosAccountType accountType, string salt, KerberosTicket armorTicket, EncryptionKey armorSessionKey) : this(domain, cName, password, accountType, salt) { this.ArmorTicket = armorTicket; this.ArmorSessionKey = armorSessionKey; this.SelectedEType = (EncryptionType)this.ArmorTicket.SessionKey.keytype.Value; }
private void UpdateTGTCachedToken(KerberosTicket tgtToken) { cacheLock.EnterWriteLock(); try { CacheTokenKey findedKey = null; int address = this.credential.GetHashCode(); foreach (var kvp in TGTTokenCache) { if (kvp.Key.CredentialAddress.Equals(address) && kvp.Key.ServerPrincipleName.Equals(this.serverName)) { findedKey = kvp.Key; break; } } if (findedKey != null) { TGTTokenCache[findedKey] = tgtToken; } else { TGTTokenCache.Add(new CacheTokenKey() { CredentialAddress = address, ServerPrincipleName = serverName }, tgtToken); } } finally { cacheLock.ExitWriteLock(); } }
/// <summary> /// Construct a Kerberos test client for FAST /// </summary> /// <param name="domain">The realm part of the client's principal identifier. /// This argument cannot be null.</param> /// <param name="cName">The account to logon the remote machine. Either user account or computer account /// This argument cannot be null.</param> /// <param name="password">The password of the user. This argument cannot be null.</param> /// <param name="accountType">The type of the logon account. User or Computer</param> public KerberosFunctionalClient(string domain, string cName, string password, KerberosAccountType accountType, KerberosTicket armorTicket, EncryptionKey armorSessionKey, string kdcAddress, int kdcPort, TransportType transportType, KerberosConstValue.OidPkt omiPkt, ITestSite baseTestSite) : base(domain, cName, password, accountType, armorTicket, armorSessionKey, kdcAddress, kdcPort, transportType, omiPkt) { testSite = baseTestSite; if (accountType == KerberosAccountType.Device) { testSite.Log.Add(LogEntryKind.Debug, "Construct Kerberos client using computer account: {0}@{1}.", cName, domain); } else { testSite.Log.Add(LogEntryKind.Debug, "Construct Kerberos client using user account: {0}@{1}.", cName, domain); } EncryptionType[] encryptionTypes = new EncryptionType[] { EncryptionType.AES256_CTS_HMAC_SHA1_96, EncryptionType.AES128_CTS_HMAC_SHA1_96, EncryptionType.RC4_HMAC, EncryptionType.RC4_HMAC_EXP, EncryptionType.DES_CBC_CRC, EncryptionType.DES_CBC_MD5 }; KerbInt32[] etypes = new KerbInt32[encryptionTypes.Length]; for (int i = 0; i < encryptionTypes.Length; i++) { etypes[i] = new KerbInt32((int)encryptionTypes[i]); } Asn1SequenceOf<KerbInt32> etype = new Asn1SequenceOf<KerbInt32>(etypes); Context.SupportedEType = etype; Context.Pvno = KerberosConstValue.KERBEROSV5; }
private KerberosTicket GetTGTCachedToken(AccountCredential inputCredential, string inputServerPrincipleName) { cacheLock.EnterReadLock(); KerberosTicket cachedTGTToken = null; CacheTokenKey findedKey = null; foreach (var kvp in TGTTokenCache) { int address = this.credential.GetHashCode(); if (kvp.Key.CredentialAddress.Equals(inputCredential) && kvp.Key.ServerPrincipleName.Equals(inputServerPrincipleName)) { findedKey = kvp.Key; break; } } if (findedKey != null) { cachedTGTToken = TGTTokenCache[findedKey]; //TODO: Remove from cache if token expired } cacheLock.ExitReadLock(); return(cachedTGTToken); }
private Authenticator CreateAuthenticator(KerberosTicket ticket, AuthorizationData data, EncryptionKey subKey, ChecksumType checksumType, byte[] checksumBody) { Authenticator plaintextAuthenticator = CreateAuthenticator(ticket, data, subKey); byte[] checkData = KerberosUtility.GetChecksum(ticket.SessionKey.keyvalue.ByteArrayValue, checksumBody, (int)KeyUsageNumber.TGS_REQ_PA_TGS_REQ_adataOR_AP_REQ_Authenticator_cksum, checksumType); plaintextAuthenticator.cksum = new Checksum(new KerbInt32((int)checksumType), new Asn1OctetString(checkData)); return(plaintextAuthenticator); }
/// <summary> /// Create a KileClient instance. /// </summary> /// <param name="domain">The realm part of the client's principal identifier. /// This argument cannot be null.</param> /// <param name="cName">The account to logon the remote machine. Either user account or computer account /// This argument cannot be null.</param> /// <param name="password">The password of the user. This argument cannot be null.</param> /// <param name="accountType">The type of the logon account. User or Computer</param> /// <param name="kdcAddress">The IP address of the KDC.</param> /// <param name="kdcPort">The port of the KDC.</param> /// <param name="transportType">Whether the transport is TCP or UDP transport.</param> /// <exception cref="System.ArgumentNullException">Thrown when the input parameter is null.</exception> public KerberosClient(string domain, string cName, string password, KerberosAccountType accountType, KerberosTicket armorTicket, EncryptionKey armorSessionKey, string kdcAddress, int kdcPort, TransportType transportType, KerberosConstValue.OidPkt oidPkt = KerberosConstValue.OidPkt.KerberosToken, string salt = null) { TransportBufferSize = KerberosConstValue.TRANSPORT_BUFFER_SIZE; this.Context = new KerberosContext(domain, cName, password, accountType, salt, armorTicket, armorSessionKey); this.kdcAddress = kdcAddress; this.kdcPort = kdcPort; this.transportType = transportType; this.oidPkt = oidPkt; this.Context.TransportType = transportType; }
/// <summary> /// Create an instance. /// </summary> public KpasswordRequest(KerberosTicket ticket, Authenticator authenticator, string newPwd, bool isAuthErrorRequired = false) { //Create KerberosApRequest long pvno = KerberosConstValue.KERBEROSV5; APOptions option = new APOptions(KerberosUtility.ConvertInt2Flags((int)ApOptions.None)); KerberosApRequest ap_req = new KerberosApRequest(pvno, option, ticket, authenticator, KeyUsageNumber.AP_REQ_Authenticator); //Create KRB_PRIV ChangePasswdData pwd_data = new ChangePasswdData(new Asn1OctetString(newPwd), null, null); priv_enc_part = new EncKrbPrivPart(); priv_enc_part.user_data = pwd_data.newpasswd; priv_enc_part.usec = authenticator.cusec; priv_enc_part.seq_number = authenticator.seq_number; priv_enc_part.s_address = new HostAddress(new KerbInt32((int)AddressType.NetBios), new Asn1OctetString(Encoding.ASCII.GetBytes(System.Net.Dns.GetHostName()))); Asn1BerEncodingBuffer asnBuffPriv = new Asn1BerEncodingBuffer(); priv_enc_part.BerEncode(asnBuffPriv, true); byte[] encAsnEncodedPriv = null; if (!isAuthErrorRequired) { encAsnEncodedPriv = KerberosUtility.Encrypt((EncryptionType)authenticator.subkey.keytype.Value, authenticator.subkey.keyvalue.ByteArrayValue, asnBuffPriv.Data, (int)KeyUsageNumber.KRB_PRIV_EncPart); } else { encAsnEncodedPriv = KerberosUtility.Encrypt((EncryptionType)authenticator.subkey.keytype.Value, authenticator.subkey.keyvalue.ByteArrayValue, asnBuffPriv.Data, (int)KeyUsageNumber.None); } var encrypted = new EncryptedData(); encrypted.etype = new KerbInt32(authenticator.subkey.keytype.Value); encrypted.cipher = new Asn1OctetString(encAsnEncodedPriv); KRB_PRIV krb_priv = new KRB_PRIV(new Asn1Integer(pvno), new Asn1Integer((long)MsgType.KRB_PRIV), encrypted); //Calculate the msg_length and ap_req_length krb_priv.BerEncode(privBuffer, true); ap_req.Request.BerEncode(apBuffer, true); version = 0x0001; ap_req_length = (ushort)apBuffer.Data.Length; msg_length = (ushort)(ap_req_length + privBuffer.Data.Length + 3 * sizeof(ushort)); //Convert Endian version = KerberosUtility.ConvertEndian(version); ap_req_length = KerberosUtility.ConvertEndian(ap_req_length); msg_length = KerberosUtility.ConvertEndian(msg_length); }
private Authenticator CreateAuthenticator(KerberosTicket ticket, AuthorizationData data, EncryptionKey subkey) { Authenticator plaintextAuthenticator = new Authenticator(); plaintextAuthenticator.authenticator_vno = new Asn1Integer(KerberosConstValue.KERBEROSV5); plaintextAuthenticator.crealm = this.Context.CName.Realm; plaintextAuthenticator.cusec = new Microseconds(DateTime.UtcNow.Millisecond); plaintextAuthenticator.ctime = KerberosUtility.CurrentKerberosTime; plaintextAuthenticator.seq_number = new KerbUInt32(0); plaintextAuthenticator.cname = ticket.TicketOwner; plaintextAuthenticator.subkey = subkey; plaintextAuthenticator.authorization_data = data; return(plaintextAuthenticator); }
/// <summary> /// Create authenticator for ChecksumType.ap_authenticator_8003 /// </summary> private Authenticator CreateAuthenticator(KerberosTicket ticket, AuthorizationData data, EncryptionKey subkey, ChecksumFlags checksumFlag) { Authenticator plaintextAuthenticator = CreateAuthenticator(ticket, data, subkey); AuthCheckSum checksum = new AuthCheckSum(); checksum.Lgth = KerberosConstValue.AUTHENTICATOR_CHECKSUM_LENGTH; checksum.Bnd = new byte[checksum.Lgth]; checksum.Flags = (int)checksumFlag; byte[] checkData = ArrayUtility.ConcatenateArrays(BitConverter.GetBytes(checksum.Lgth), checksum.Bnd, BitConverter.GetBytes(checksum.Flags)); plaintextAuthenticator.cksum = new Checksum(new KerbInt32((int)ChecksumType.ap_authenticator_8003), new Asn1OctetString(checkData)); return(plaintextAuthenticator); }
/// <summary> /// Create an instance. /// </summary> public KerberosApRequest(long pvno, APOptions ap_options, KerberosTicket ticket, Authenticator authenticator, KeyUsageNumber keyUsageNumber) { Asn1BerEncodingBuffer asnBuffPlainAuthenticator = new Asn1BerEncodingBuffer(); authenticator.BerEncode(asnBuffPlainAuthenticator, true); KerberosUtility.OnDumpMessage("KRB5:Authenticator", "Authenticator in AP-REQ structure", KerberosUtility.DumpLevel.PartialMessage, asnBuffPlainAuthenticator.Data); byte[] encAsnEncodedAuth = KerberosUtility.Encrypt((EncryptionType)ticket.SessionKey.keytype.Value, ticket.SessionKey.keyvalue.ByteArrayValue, asnBuffPlainAuthenticator.Data, (int)keyUsageNumber); var encrypted = new EncryptedData(); encrypted.etype = new KerbInt32(ticket.SessionKey.keytype.Value); encrypted.cipher = new Asn1OctetString(encAsnEncodedAuth); long msg_type = (long)MsgType.KRB_AP_REQ; Request = new AP_REQ(new Asn1Integer(pvno), new Asn1Integer(msg_type), ap_options, ticket.Ticket, encrypted); Authenticator = authenticator; }
/// <summary> /// Construct a kpassword test client /// </summary> /// <param name="kdcAddress">The IP address of the KDC.</param> /// <param name="kdcPort">The port of the KDC for Kpassword.</param> /// <param name="transportType">Whether the transport is TCP or UDP transport.</param> /// <param name="ticket">The ticket authorized to change password</param> public KpasswdTestClient(string kdcAddress, int kdcPort, TransportType transportType, KerberosTicket ticket) : base(kdcAddress, kdcPort, transportType) { testSite = TestClassBase.BaseTestSite; this.Context.Ticket = ticket; }
/// <summary> /// Create authenticator for ChecksumType.ap_authenticator_8003 /// </summary> private Authenticator CreateAuthenticator( KerberosTicket ticket, AuthorizationData data, EncryptionKey subkey, ChecksumFlags checksumFlag ) { Authenticator plaintextAuthenticator = CreateAuthenticator(ticket, data, subkey); AuthCheckSum checksum = new AuthCheckSum(); checksum.Lgth = KerberosConstValue.AUTHENTICATOR_CHECKSUM_LENGTH; checksum.Bnd = new byte[checksum.Lgth]; checksum.Flags = (int)checksumFlag; byte[] checkData = ArrayUtility.ConcatenateArrays(BitConverter.GetBytes(checksum.Lgth), checksum.Bnd, BitConverter.GetBytes(checksum.Flags)); plaintextAuthenticator.cksum = new Checksum(new KerbInt32((int)ChecksumType.ap_authenticator_8003), new Asn1OctetString(checkData)); return plaintextAuthenticator; }
/// <summary> /// Kerberos Client Initialize without server token /// </summary> private void ClientInitialize() { this.ApRequestAuthenticator = null; // Create and send AS request for pre-authentication KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; KerberosTicket ticket = this.GetTGTCachedToken(this.credential, this.serverName); if (ticket == null) { this.SendAsRequest(options, null); // Expect recieve preauthentication required error METHOD_DATA methodData; this.ExpectPreauthRequiredError(out methodData); // Create sequence of PA data string timeStamp = KerberosUtility.CurrentKerberosTime.Value; PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp, 0, this.Context.SelectedEType, this.Context.CName.Password, this.Context.CName.Salt); PaPacRequest paPacRequest = new PaPacRequest(true); PaPacOptions paPacOptions = new PaPacOptions(PacOptions.Claims | PacOptions.ForwardToFullDc); Asn1SequenceOf <PA_DATA> seqOfPaData_AS = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data, paPacOptions.Data }); // Create and send AS request for TGT KerberosAsRequest asRequest = this.SendAsRequest(options, seqOfPaData_AS); // Expect TGT(AS) Response from KDC KerberosAsResponse asResponse = this.ExpectAsResponse(); // Create and send TGS request Asn1SequenceOf <PA_DATA> seqOfPaData_TGS = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paPacRequest.Data, paPacOptions.Data }); this.SendTgsRequest(this.serverName, options, seqOfPaData_TGS); // Expect TGS Response from KDC KerberosTgsResponse tgsResponse = this.ExpectTgsResponse(); this.UpdateTGTCachedToken(this.Context.Ticket); } else { // Restore SessionKey and Ticket from cache this.Context.SessionKey = ticket.SessionKey; this.Context.ApSessionKey = ticket.SessionKey; this.Context.Ticket = ticket; this.Context.SelectedEType = (EncryptionType)Context.Ticket.Ticket.enc_part.etype.Value; } // cache this.Context.Ticket; ApOptions apOption; GetFlagsByContextAttribute(out apOption); AuthorizationData data = null; EncryptionKey subkey = KerberosUtility.GenerateKey(this.client.Context.ContextKey); this.token = this.CreateGssApiToken(apOption, data, subkey, this.Context.ChecksumFlag, KerberosConstValue.GSSToken.GSSAPI); bool isMutualAuth = (contextAttribute & ClientSecurityContextAttribute.MutualAuth) == ClientSecurityContextAttribute.MutualAuth; bool isDceStyle = (contextAttribute & ClientSecurityContextAttribute.DceStyle) == ClientSecurityContextAttribute.DceStyle; if (isMutualAuth || isDceStyle) { this.needContinueProcessing = true; } else { this.needContinueProcessing = false; } }
public PaFxFastReq CreateTgsPaFxFast( EncryptionKey armorKey, KerberosTicket armorTicket, FastOptions fastOptions, ApOptions apOptions, Asn1SequenceOf<PA_DATA> seqPaData, string sName, byte[] apReq, IFastArmor armor = null ) { string domain = this.Context.Realm.Value; PrincipalName sname = new PrincipalName(new KerbInt32((int)PrincipalType.NT_SRV_INST), KerberosUtility.String2SeqKerbString(sName.Split('/'))); KDC_REQ_BODY innerKdcReqBody = CreateKdcRequestBody(KdcOptions.CANONICALIZE | KdcOptions.FORWARDABLE | KdcOptions.RENEWABLE, sname); //Generate checksum var checksumType = KerberosUtility.GetChecksumType(Context.SelectedEType); var chksum = KerberosUtility.GetChecksum( armorKey.keyvalue.ByteArrayValue, apReq, (int)KeyUsageNumber.FAST_REQ_CHECKSUM, checksumType); Checksum checkSum = new Checksum(new KerbInt32((int)checksumType), new Asn1OctetString(chksum)); KerberosFastRequest fastReq = new KerberosFastRequest(fastOptions, seqPaData, innerKdcReqBody); KerberosArmoredRequest armoredReq = new KerberosArmoredRequest(armor, checkSum, (long)Context.SelectedEType, armorKey.keyvalue.ByteArrayValue, fastReq); PA_FX_FAST_REQUEST paFxFastReq = new PA_FX_FAST_REQUEST(); paFxFastReq.SetData(PA_FX_FAST_REQUEST.armored_data, armoredReq.FastArmoredReq); PaFxFastReq paFxfast = new PaFxFastReq(paFxFastReq); return paFxfast; }
/// <summary> /// Create a KileClient instance. /// </summary> /// <param name="domain">The realm part of the client's principal identifier. /// This argument cannot be null.</param> /// <param name="cName">The account to logon the remote machine. Either user account or computer account /// This argument cannot be null.</param> /// <param name="password">The password of the user. This argument cannot be null.</param> /// <param name="accountType">The type of the logon account. User or Computer</param> /// <param name="kdcAddress">The IP address of the KDC.</param> /// <param name="kdcPort">The port of the KDC.</param> /// <param name="transportType">Whether the transport is TCP or UDP transport.</param> /// <exception cref="System.ArgumentNullException">Thrown when the input parameter is null.</exception> public KerberosClient(string domain, string cName, string password, KerberosAccountType accountType, KerberosTicket armorTicket, EncryptionKey armorSessionKey, string kdcAddress, int kdcPort, TransportType transportType, KerberosConstValue.OidPkt oidPkt = KerberosConstValue.OidPkt.KerberosToken, string salt = null) : this(domain, cName, password, accountType, armorTicket, armorSessionKey, IPAddress.Parse(kdcAddress), kdcPort, transportType, oidPkt, salt) { }
private Authenticator CreateAuthenticator( KerberosTicket ticket, AuthorizationData data, EncryptionKey subkey, ChecksumType checksumType, byte[] checksumBody ) { Authenticator plaintextAuthenticator = CreateAuthenticator(ticket, data, subkey); byte[] checkData = KerberosUtility.GetChecksum(ticket.SessionKey.keyvalue.ByteArrayValue, checksumBody, (int)KeyUsageNumber.TGS_REQ_PA_TGS_REQ_adataOR_AP_REQ_Authenticator_cksum, checksumType); plaintextAuthenticator.cksum = new Checksum(new KerbInt32((int)checksumType), new Asn1OctetString(checkData)); return plaintextAuthenticator; }
private Authenticator CreateAuthenticator( KerberosTicket ticket, AuthorizationData data, EncryptionKey subkey ) { Authenticator plaintextAuthenticator = new Authenticator(); plaintextAuthenticator.authenticator_vno = new Asn1Integer(KerberosConstValue.KERBEROSV5); plaintextAuthenticator.crealm = Context.CName.Realm; plaintextAuthenticator.cusec = new Microseconds(0); plaintextAuthenticator.ctime = KerberosUtility.CurrentKerberosTime; plaintextAuthenticator.seq_number = new KerbUInt32(0); plaintextAuthenticator.cname = ticket.TicketOwner; plaintextAuthenticator.subkey = subkey; plaintextAuthenticator.authorization_data = data; return plaintextAuthenticator; }
private KerberosApRequest CreateApRequest(APOptions option, KerberosTicket ticket, EncryptionKey subkey, AuthorizationData data, KeyUsageNumber keyUsageNumber, ChecksumType checksumType, byte[] checksumBody) { Authenticator authenticator = CreateAuthenticator(ticket, data, subkey, checksumType, checksumBody); KerberosApRequest apReq = new KerberosApRequest(Context.Pvno, option, ticket, authenticator, keyUsageNumber); return apReq; }