/// <summary> /// Unwraps a proxy-encoded message for further processing /// </summary> /// <param name="mode">Indicates whether the proxy message includes the length prefix or not</param> /// <returns>Returns the unwrapped message</returns> public ReadOnlyMemory <byte> UnwrapMessage(out KdcProxyMessageMode mode) { var prefix = this.KerbMessage.Slice(0, 4).AsLong(); var message = this.KerbMessage; if (prefix != this.KerbMessage.Length - 4) { var possibleMessageType = KrbMessage.DetectMessageType(this.KerbMessage); if (!possibleMessageType.IsValidMessageType()) { throw new InvalidOperationException( $"Proxy message length {prefix} doesn't match actual message length {message.Length}" ); } mode = KdcProxyMessageMode.NoPrefix; } else { message = this.KerbMessage.Slice(4); mode = KdcProxyMessageMode.IncludeLengthPrefix; } return(message); }
/// <summary> /// Wraps a standard KDC message into a proxy message /// </summary> /// <param name="message">The message to wrap</param> /// <param name="domain">The optional domain hint for downstream processing</param> /// <param name="hint">A DC location hint for downstream processing</param> /// <param name="mode">The encoding mode which indicates whether the message should include the length prefix or not</param> /// <returns>Returns a formed KDC Message</returns> public static KdcProxyMessage WrapMessage( ReadOnlyMemory <byte> message, string domain = null, DcLocatorHint?hint = null, KdcProxyMessageMode mode = KdcProxyMessageMode.IncludeLengthPrefix ) { var proxyMessage = new KdcProxyMessage() { TargetDomain = domain, DcLocatorHint = hint }; if (mode == KdcProxyMessageMode.NoPrefix) { proxyMessage.KerbMessage = message; } else { proxyMessage.KerbMessage = Tcp.FormatKerberosMessageStream(message); } return(proxyMessage); }
private static ReadOnlyMemory <byte> EncodeProxyResponse(ReadOnlyMemory <byte> response, KdcProxyMessageMode mode) { return(KdcProxyMessage.WrapMessage(response, mode: mode).Encode()); }