/// <summary> /// Checks there's a Kerberos Ticket in current user's Windows Ticket Cache matched with the service principal name. /// If there's a valid ticket, then show the Ticket Information on the console. /// </summary> /// <returns></returns> public bool ShowCachedTicket() { try { byte[] ticket = KerberosSupplementalTicketManager.GetKerberosTicketFromWindowsTicketCache(_kerberosServicePrincipalName, _logonId); if (ticket != null && ticket.Length > 32) { var encode = Convert.ToBase64String(ticket); AADKerberosLogger.PrintLines(2); AADKerberosLogger.Save($"---Find cached Ticket: {ticket.Length} bytes"); AADKerberosLogger.PrintBinaryData(ticket); TicketDecoder decoder = new TicketDecoder(); decoder.ShowApReqTicket(encode); return(true); } Console.WriteLine($"There's no ticket associated with '{_kerberosServicePrincipalName}'"); } catch (Win32Exception ex) { Console.WriteLine($"ERROR while finding Kerberos Ticket for '{_kerberosServicePrincipalName}': {ex.Message}"); } return(false); }
/// <summary> /// Shows the Kerberos Ticket included in an authentication token with KrbCred format /// which is used to transfer Kerberos credentials between applications. /// Reference: /// The Unencrypted Form of Kerberos 5 KRB-CRED Message /// https://tools.ietf.org/html/rfc6448 /// </summary> /// <param name="message"></param> internal void ShowKrbCredTicket(string message) { var krbAsRepBytes = Convert.FromBase64String(message); var krbCred = KrbCred.DecodeApplication(krbAsRepBytes); Assert.IsNotNull(krbCred); var credPart = krbCred.Validate(); Assert.IsNotNull(credPart); AADKerberosLogger.PrintLines(2); AADKerberosLogger.Save("KRB-CRED Supplemental Ticket -----------------------------"); AADKerberosLogger.Save(" ProtocolVersionNumber: " + krbCred.ProtocolVersionNumber); AADKerberosLogger.Save(" Message Type: " + krbCred.MessageType); AADKerberosLogger.Save(" # of Tickets: " + krbCred.Tickets.Length); for (int i = 0; i < krbCred.Tickets.Length; i++) { var ticket = krbCred.Tickets[i]; var ticketInfo = credPart.TicketInfo[i]; var key = new byte[ticketInfo.Key.KeyValue.Length]; ticketInfo.Key.KeyValue.CopyTo(key); AADKerberosLogger.Save(" Number: " + ticket.TicketNumber); AADKerberosLogger.Save(" Realm: " + ticket.Realm); AADKerberosLogger.Save(" SName: " + ticket.SName.FullyQualifiedName); ShowEncryptedDataPart("EncryptedPart", ticket.EncryptedPart); AADKerberosLogger.Save(" Ticket.Flags: " + ticketInfo.Flags); AADKerberosLogger.Save(" Ticket.Realm: " + ticketInfo.Realm); AADKerberosLogger.Save(" Ticket.PName: " + ticketInfo.PName.FullyQualifiedName); AADKerberosLogger.Save(" Ticket.SRealm: " + ticketInfo.SRealm); AADKerberosLogger.Save(" Ticket.SName: " + ticketInfo.SName.FullyQualifiedName); AADKerberosLogger.Save(" Ticket.AuthTime: " + ticketInfo.AuthTime); AADKerberosLogger.Save(" Ticket.StartTime: " + ticketInfo.StartTime); AADKerberosLogger.Save(" Ticket.EndTime: " + ticketInfo.EndTime); AADKerberosLogger.Save(" Ticket.RenewTill: " + ticketInfo.RenewTill); ShowEncrytionKey("Ticket.Key", ticketInfo.Key); if (ticketInfo.AuthorizationData == null) { AADKerberosLogger.Save(" Ticket.AuthorizationData:"); } else { for (int j = 0; j < ticketInfo.AuthorizationData.Length; j++) { ShowAuthorizationData("Ticket.AuthorizationData", ticketInfo.AuthorizationData[j]); } } AADKerberosLogger.Save(""); } }
/// <summary> /// Checks there's a valid Kerberos Ticket information within the received authentication token. /// If there's a valid one, show the ticket information and cache it into current user's /// Windows Ticket Cache so that it can be shared with other Kerberos-aware applications. /// </summary> /// <param name="result">The <see cref="AuthenticationResult"/> from token request.</param> private void ProcessKerberosTicket(AuthenticationResult result) { KerberosSupplementalTicket ticket; if (_ticketContainer == KerberosTicketContainer.IdToken) { // 1. Get the Kerberos Ticket contained in the Id Token. ticket = KerberosSupplementalTicketManager.FromIdToken(result.IdToken); if (ticket == null) { AADKerberosLogger.Save("ERROR: There's no Kerberos Ticket information within the IdToken."); return; } AADKerberosLogger.PrintLines(2); try { // 2. Save the Kerberos Ticket into current user's Windows Ticket Cache. KerberosSupplementalTicketManager.SaveToWindowsTicketCache(ticket, _logonId); AADKerberosLogger.Save("---Kerberos Ticket cached into user's Ticket Cache\n"); } catch (Win32Exception ex) { AADKerberosLogger.Save("---Kerberos Ticket caching failed: " + ex.Message); } AADKerberosLogger.PrintLines(2); AADKerberosLogger.Save("KerberosSupplementalTicket {"); AADKerberosLogger.Save(" Client Key: " + ticket.ClientKey); AADKerberosLogger.Save(" Key Type: " + ticket.KeyType); AADKerberosLogger.Save(" Errorr Message: " + ticket.ErrorMessage); AADKerberosLogger.Save(" Realm: " + ticket.Realm); AADKerberosLogger.Save(" Service Principal Name: " + ticket.ServicePrincipalName); AADKerberosLogger.Save(" Client Name: " + ticket.ClientName); AADKerberosLogger.Save(" KerberosMessageBuffer: " + ticket.KerberosMessageBuffer); AADKerberosLogger.Save("}\n"); // shows detailed ticket information. TicketDecoder decoder = new TicketDecoder(); decoder.ShowKrbCredTicket(ticket.KerberosMessageBuffer); } else { AADKerberosLogger.PrintLines(2); AADKerberosLogger.Save("Kerberos Ticket handling is not supported for access token."); } }
/// <summary> /// Shows the internal information of a cached Kerberos Ticket in current user's Windows Ticket Cache /// with KRB_AP_REQ format. /// Reference: /// The Kerberos Network Authentication Service (V5) /// https://tools.ietf.org/html/rfc4120#section-3.2.1 /// </summary> /// <param name="messaage"></param> internal void ShowApReqTicket(string messaage) { var tokenBytes = System.Convert.FromBase64String(messaage); var contextToken = MessageParser.Parse <KerberosContextToken>(tokenBytes); Assert.IsNotNull(contextToken); Assert.IsNotNull(contextToken.KrbApReq); var req = contextToken.KrbApReq; Assert.IsNotNull(req.Ticket); AADKerberosLogger.PrintLines(2); AADKerberosLogger.Save("AP-REQ Cached Ticket----------------------------------------"); AADKerberosLogger.Save(" Protocol Version Number: " + req.ProtocolVersionNumber); AADKerberosLogger.Save(" MessageType: " + req.MessageType); AADKerberosLogger.Save(" ApOptions: " + req.ApOptions); AADKerberosLogger.Save(" Ticket.TicketNumber: " + req.Ticket.TicketNumber); AADKerberosLogger.Save(" Ticket.Realm: " + req.Ticket.Realm); AADKerberosLogger.Save(" Ticket.SName: " + req.Ticket.SName.FullyQualifiedName); ShowEncryptedDataPart("Ticket.EncryptedPart", req.Ticket.EncryptedPart); ShowEncryptedDataPart("Ticket.Authenticator", req.Authenticator); }