/// <summary> /// Delete target peer for socket. /// </summary> /// <param name="socket">The socket to set.</param> /// <param name="peer_address">Peer address.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The NT status code.</returns> public static NtStatus DeletePeerTargetName(this Socket socket, IPEndPoint peer_address, bool throw_on_error) { byte[] addr = peer_address.ToArray(); return(SocketNativeMethods.WSADeleteSocketPeerTargetName( socket.Handle, addr, addr.Length, IntPtr.Zero, IntPtr.Zero).GetNtStatus(throw_on_error)); }
/// <summary> /// Query the socket security information. /// </summary> /// <param name="socket">The socket to query.</param> /// <param name="peer_address">Optional peer address. Only needed for datagram sockets.</param> /// <param name="desired_access">Optional desired access for peer tokens. If set to None then no tokens will be returned.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The socket security information.</returns> public static NtResult <SocketSecurityInformation> QuerySecurity(this Socket socket, IPEndPoint peer_address, TokenAccessRights desired_access, bool throw_on_error) { var query = new SOCKET_SECURITY_QUERY_TEMPLATE_IPSEC2 { SecurityProtocol = SOCKET_SECURITY_PROTOCOL.IPsec2, PeerAddress = peer_address.ToSocketStorage(), PeerTokenAccessMask = desired_access, FieldMask = SocketSecurityQueryFieldMask.MmSaId | SocketSecurityQueryFieldMask.QmSaId }; using (var template = query.ToBuffer()) { int length = 0; SocketNativeMethods.WSAQuerySocketSecurity(socket.Handle, template, template.Length, SafeHGlobalBuffer.Null, ref length, IntPtr.Zero, IntPtr.Zero); Win32Error error = SocketNativeMethods.WSAGetLastError(); if (error != Win32Error.WSAEMSGSIZE) { return(error.CreateResultFromDosError <SocketSecurityInformation>(throw_on_error)); } using (var buffer = new SafeStructureInOutBuffer <SOCKET_SECURITY_QUERY_INFO>(length, false)) { return(SocketNativeMethods.WSAQuerySocketSecurity(socket.Handle, template, template.Length, buffer, ref length, IntPtr.Zero, IntPtr.Zero).CreateWSAResult(throw_on_error, () => new SocketSecurityInformation(buffer))); } } }
private static NtResult <T> CreateWSAResult <T>(this int error, bool throw_on_error, Func <T> create_func) { if (error >= 0) { return(create_func().CreateResult()); } return(SocketNativeMethods.WSAGetLastError().CreateResultFromDosError <T>(throw_on_error)); }
private static NtStatus GetNtStatus(this int error, bool throw_on_error) { if (error >= 0) { return(NtStatus.STATUS_SUCCESS); } return(SocketNativeMethods.WSAGetLastError().ToNtException(throw_on_error)); }
/// <summary> /// Set the socket security information. /// </summary> /// <param name="socket">The socket to set.</param> /// <param name="settings">The security settings.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The NT status code.</returns> public static NtStatus SetSecurity(this Socket socket, SocketSecuritySettings settings, bool throw_on_error) { using (var buffer = settings?.ToBuffer() ?? SafeHGlobalBuffer.Null) { return(SocketNativeMethods.WSASetSocketSecurity(socket.Handle, buffer, buffer.Length, IntPtr.Zero, IntPtr.Zero).GetNtStatus(throw_on_error)); } }
/// <summary> /// Set target peer for socket. /// </summary> /// <param name="socket">The socket to set.</param> /// <param name="target_name">The target name.</param> /// <param name="peer_address">Optional peer address. Only needed for datagram sockets.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The NT status code.</returns> public static NtStatus SetPeerTargetName(this Socket socket, string target_name, IPEndPoint peer_address, bool throw_on_error) { byte[] target_name_bytes = Encoding.Unicode.GetBytes(target_name); int target_name_length = target_name_bytes.Length; int total_length = Marshal.SizeOf(typeof(SOCKET_PEER_TARGET_NAME)) + target_name_bytes.Length; using (var buffer = new SOCKET_PEER_TARGET_NAME() { SecurityProtocol = SOCKET_SECURITY_PROTOCOL.IPsec2, PeerAddress = peer_address.ToSocketStorage(), PeerTargetNameStringLen = target_name_length }.ToBuffer(total_length, false)) { buffer.Data.WriteBytes(target_name_bytes); return(SocketNativeMethods.WSASetSocketPeerTargetName( socket.Handle, buffer, buffer.Length, IntPtr.Zero, IntPtr.Zero).GetNtStatus(throw_on_error)); } }
/// <summary> /// Impersonate the socket's peer. /// </summary> /// <param name="socket">The socket to impersonate.</param> /// <param name="peer_address">Optional peer address. Only needed for datagram sockets.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The impersonation context.</returns> public static NtResult <ThreadImpersonationContext> Impersonate(this Socket socket, IPEndPoint peer_address, bool throw_on_error) { byte[] addr = peer_address?.ToArray(); return(SocketNativeMethods.WSAImpersonateSocketPeer(socket.Handle, addr, addr?.Length ?? 0) .CreateWSAResult(throw_on_error, () => new ThreadImpersonationContext())); }