public void NegotiateStream_StreamToStream_Authentication_TargetName_Success()
        {
            string targetName = "testTargetName";

            VirtualNetwork network = new VirtualNetwork();

            using (var clientStream = new VirtualNetworkStream(network, isServer: false))
            using (var serverStream = new VirtualNetworkStream(network, isServer: true))
            using (var client = new NegotiateStream(clientStream))
            using (var server = new NegotiateStream(serverStream))
            {
                Assert.False(client.IsAuthenticated);
                Assert.False(server.IsAuthenticated);

                Task[] auth = new Task[2];

                auth[0] = client.AuthenticateAsClientAsync(CredentialCache.DefaultNetworkCredentials, targetName);
                auth[1] = server.AuthenticateAsServerAsync();

                bool finished = Task.WaitAll(auth, TestConfiguration.PassingTestTimeoutMilliseconds);
                Assert.True(finished, "Handshake completed in the allotted time");

                // Expected Client property values:
                Assert.True(client.IsAuthenticated);
                Assert.Equal(TokenImpersonationLevel.Identification, client.ImpersonationLevel);
                Assert.Equal(true, client.IsEncrypted);
                Assert.Equal(false, client.IsMutuallyAuthenticated);
                Assert.Equal(false, client.IsServer);
                Assert.Equal(true, client.IsSigned);
                Assert.Equal(false, client.LeaveInnerStreamOpen);

                IIdentity serverIdentity = client.RemoteIdentity;
                Assert.Equal("NTLM", serverIdentity.AuthenticationType);
                Assert.Equal(true, serverIdentity.IsAuthenticated);
                Assert.Equal(targetName, serverIdentity.Name);

                // Expected Server property values:
                Assert.True(server.IsAuthenticated);
                Assert.Equal(TokenImpersonationLevel.Identification, server.ImpersonationLevel);
                Assert.Equal(true, server.IsEncrypted);
                Assert.Equal(false, server.IsMutuallyAuthenticated);
                Assert.Equal(true, server.IsServer);
                Assert.Equal(true, server.IsSigned);
                Assert.Equal(false, server.LeaveInnerStreamOpen);

                IIdentity clientIdentity = server.RemoteIdentity;
                Assert.Equal("NTLM", clientIdentity.AuthenticationType);

                Assert.Equal(true, clientIdentity.IsAuthenticated);
                IdentityValidator.AssertIsCurrentIdentity(clientIdentity);
            }
        }
Beispiel #2
0
 protected override Task AuthenticateAsServerAsync(NegotiateStream server) =>
 server.AuthenticateAsServerAsync();
Beispiel #3
0
 protected abstract Task AuthenticateAsServerAsync(NegotiateStream server);
Beispiel #4
0
        public void NegotiateStream_StreamToStream_Authentication_EmptyCredentials_Fails()
        {
            string targetName = "testTargetName";

            // Ensure there is no confusion between DefaultCredentials / DefaultNetworkCredentials and a
            // NetworkCredential object with empty user, password and domain.
            NetworkCredential emptyNetworkCredential = new NetworkCredential("", "", "");

            Assert.NotEqual(emptyNetworkCredential, CredentialCache.DefaultCredentials);
            Assert.NotEqual(emptyNetworkCredential, CredentialCache.DefaultNetworkCredentials);

            VirtualNetwork network = new VirtualNetwork();

            using (var clientStream = new VirtualNetworkStream(network, isServer: false))
                using (var serverStream = new VirtualNetworkStream(network, isServer: true))
                    using (var client = new NegotiateStream(clientStream))
                        using (var server = new NegotiateStream(serverStream))
                        {
                            Assert.False(client.IsAuthenticated);
                            Assert.False(server.IsAuthenticated);

                            Task[] auth = new Task[2];

                            auth[0] = AuthenticateAsClientAsync(client, emptyNetworkCredential, targetName);
                            auth[1] = AuthenticateAsServerAsync(server);

                            bool finished = Task.WaitAll(auth, TestConfiguration.PassingTestTimeoutMilliseconds);
                            Assert.True(finished, "Handshake completed in the allotted time");

                            // Expected Client property values:
                            Assert.True(client.IsAuthenticated);
                            Assert.Equal(TokenImpersonationLevel.Identification, client.ImpersonationLevel);
                            Assert.Equal(true, client.IsEncrypted);
                            Assert.Equal(false, client.IsMutuallyAuthenticated);
                            Assert.Equal(false, client.IsServer);
                            Assert.Equal(true, client.IsSigned);
                            Assert.Equal(false, client.LeaveInnerStreamOpen);

                            IIdentity serverIdentity = client.RemoteIdentity;
                            Assert.Equal("NTLM", serverIdentity.AuthenticationType);
                            Assert.Equal(true, serverIdentity.IsAuthenticated);
                            Assert.Equal(targetName, serverIdentity.Name);

                            // Expected Server property values:
                            Assert.True(server.IsAuthenticated);
                            Assert.Equal(TokenImpersonationLevel.Identification, server.ImpersonationLevel);
                            Assert.Equal(true, server.IsEncrypted);
                            Assert.Equal(false, server.IsMutuallyAuthenticated);
                            Assert.Equal(true, server.IsServer);
                            Assert.Equal(true, server.IsSigned);
                            Assert.Equal(false, server.LeaveInnerStreamOpen);

                            IIdentity clientIdentity = server.RemoteIdentity;
                            Assert.Equal("NTLM", clientIdentity.AuthenticationType);

                            // TODO #5241: Behavior difference:
                            Assert.Equal(false, clientIdentity.IsAuthenticated);
                            // On .Net Desktop: Assert.Equal(true, clientIdentity.IsAuthenticated);

                            IdentityValidator.AssertHasName(clientIdentity, @"NT AUTHORITY\ANONYMOUS LOGON");
                        }
        }
Beispiel #5
0
 protected override Task AuthenticateAsClientAsync(NegotiateStream client, NetworkCredential credential, string targetName) =>
 Task.Run(() => client.AuthenticateAsClient(credential, targetName, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification));
Beispiel #6
0
        public async Task NegotiateStream_StreamToStream_Authentication_EmptyCredentials_Fails()
        {
            string targetName = "testTargetName";

            // Ensure there is no confusion between DefaultCredentials / DefaultNetworkCredentials and a
            // NetworkCredential object with empty user, password and domain.
            NetworkCredential emptyNetworkCredential = new NetworkCredential("", "", "");

            Assert.NotEqual(emptyNetworkCredential, CredentialCache.DefaultCredentials);
            Assert.NotEqual(emptyNetworkCredential, CredentialCache.DefaultNetworkCredentials);

            VirtualNetwork network = new VirtualNetwork();

            using (var clientStream = new VirtualNetworkStream(network, isServer: false))
                using (var serverStream = new VirtualNetworkStream(network, isServer: true))
                    using (var client = new NegotiateStream(clientStream))
                        using (var server = new NegotiateStream(serverStream))
                        {
                            Assert.False(client.IsAuthenticated);
                            Assert.False(server.IsAuthenticated);

                            Task[] auth = new Task[2];

                            auth[0] = AuthenticateAsClientAsync(client, emptyNetworkCredential, targetName);
                            auth[1] = AuthenticateAsServerAsync(server);

                            await TestConfiguration.WhenAllOrAnyFailedWithTimeout(auth);

                            // Expected Client property values:
                            Assert.True(client.IsAuthenticated);
                            Assert.Equal(TokenImpersonationLevel.Identification, client.ImpersonationLevel);
                            Assert.Equal(true, client.IsEncrypted);
                            Assert.Equal(false, client.IsMutuallyAuthenticated);
                            Assert.Equal(false, client.IsServer);
                            Assert.Equal(true, client.IsSigned);
                            Assert.Equal(false, client.LeaveInnerStreamOpen);

                            IIdentity serverIdentity = client.RemoteIdentity;
                            Assert.Equal("NTLM", serverIdentity.AuthenticationType);
                            Assert.Equal(true, serverIdentity.IsAuthenticated);
                            Assert.Equal(targetName, serverIdentity.Name);

                            // Expected Server property values:
                            Assert.True(server.IsAuthenticated);
                            Assert.Equal(TokenImpersonationLevel.Identification, server.ImpersonationLevel);
                            Assert.Equal(true, server.IsEncrypted);
                            Assert.Equal(false, server.IsMutuallyAuthenticated);
                            Assert.Equal(true, server.IsServer);
                            Assert.Equal(true, server.IsSigned);
                            Assert.Equal(false, server.LeaveInnerStreamOpen);

                            IIdentity clientIdentity = server.RemoteIdentity;
                            Assert.Equal("NTLM", clientIdentity.AuthenticationType);

                            // TODO #5241: Behavior difference:
                            Assert.Equal(false, clientIdentity.IsAuthenticated);
                            // On .Net Desktop: Assert.Equal(true, clientIdentity.IsAuthenticated);

                            IdentityValidator.AssertHasName(clientIdentity, new SecurityIdentifier(WellKnownSidType.AnonymousSid, null).Translate(typeof(NTAccount)).Value);
                        }
        }
        public void NegotiateStream_StreamToStream_Successive_ClientWrite_Async_Success()
        {
            byte[] recvBuf = new byte[_sampleMsg.Length];
            VirtualNetwork network = new VirtualNetwork();

            using (var clientStream = new VirtualNetworkStream(network, isServer: false))
            using (var serverStream = new VirtualNetworkStream(network, isServer: true))
            using (var client = new NegotiateStream(clientStream))
            using (var server = new NegotiateStream(serverStream))
            {
                Assert.False(client.IsAuthenticated);
                Assert.False(server.IsAuthenticated);

                Task[] auth = new Task[2];
                auth[0] = client.AuthenticateAsClientAsync();
                auth[1] = server.AuthenticateAsServerAsync();

                bool finished = Task.WaitAll(auth, TestConfiguration.PassingTestTimeoutMilliseconds);
                Assert.True(finished, "Handshake completed in the allotted time");

                auth[0] = client.WriteAsync(_sampleMsg, 0, _sampleMsg.Length);
                auth[1] = server.ReadAsync(recvBuf, 0, _sampleMsg.Length);
                finished = Task.WaitAll(auth, TestConfiguration.PassingTestTimeoutMilliseconds);
                Assert.True(finished, "Send/receive completed in the allotted time");
                Assert.True(_sampleMsg.SequenceEqual(recvBuf));

                auth[0] = client.WriteAsync(_sampleMsg, 0, _sampleMsg.Length);
                auth[1] = server.ReadAsync(recvBuf, 0, _sampleMsg.Length);
                finished = Task.WaitAll(auth, TestConfiguration.PassingTestTimeoutMilliseconds);
                Assert.True(finished, "Send/receive completed in the allotted time");
                Assert.True(_sampleMsg.SequenceEqual(recvBuf));
            }
        }
 protected override Task AuthenticateAsServerAsync(NegotiateStream server) =>
     Task.Factory.FromAsync(server.BeginAuthenticateAsServer, server.EndAuthenticateAsServer, null);
 protected override IAsyncResult OnBegin(Stream stream, AsyncCallback callback)
 {
     this.negotiateStream = new NegotiateStream(stream);
     return(this.negotiateStream.BeginAuthenticateAsServer(this.acceptor.parent.ServerCredential, this.acceptor.parent.ProtectionLevel, TokenImpersonationLevel.Identification, callback, this));
 }
        /// <summary>
        /// Authenticates the client stream
        /// </summary>
        /// <param name="stream">The stream to autenticate</param>
        /// <param name="userToken">the user token associated with the identity match</param>
        /// <param name="additionalChallenge">Additional data that much match between the client and server
        /// for the connection to succeed.</param>
        /// <returns>true if successful authentication. False otherwise.</returns>
        public bool TryAuthenticateAsServer(Stream stream, out Guid userToken, byte[] additionalChallenge = null)
        {
            userToken = Guid.Empty;
            if (additionalChallenge is null)
            {
                additionalChallenge = new byte[] { }
            }
            ;
            if (additionalChallenge.Length > short.MaxValue)
            {
                throw new ArgumentOutOfRangeException("additionalChallenge", "Must be less than 32767 bytes");
            }

            using (NegotiateStream negotiateStream = new NegotiateStream(stream, true))
            {
                try
                {
                    negotiateStream.AuthenticateAsServer(CredentialCache.DefaultNetworkCredentials, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification);
                }
                catch (Exception ex)
                {
                    Log.Publish(MessageLevel.Info, "Security Login Failed", "Attempting an integrated security login failed", null, ex);
                    return(false);
                }

                negotiateStream.Write((short)additionalChallenge.Length);
                if (additionalChallenge.Length > 0)
                {
                    negotiateStream.Write(additionalChallenge);
                }
                negotiateStream.Flush();

                int len = negotiateStream.ReadInt16();
                if (len < 0)
                {
                    Log.Publish(MessageLevel.Info, "Security Login Failed", "Attempting an integrated security login failed", "Challenge Length is invalid: " + len.ToString());
                    return(false);
                }

                byte[] remoteChallenge;
                if (len == 0)
                {
                    remoteChallenge = new byte[0];
                }
                else
                {
                    remoteChallenge = negotiateStream.ReadBytes(len);
                }

                if (remoteChallenge.SecureEquals(additionalChallenge))
                {
                    if (Users.TryGetToken(negotiateStream.RemoteIdentity, out userToken))
                    {
                        return(true);
                    }
                    Log.Publish(MessageLevel.Info, "Security Login Failed", "Attempting an integrated security login failed", "User did not exist in the database: " + negotiateStream.RemoteIdentity.ToString());
                    return(false);
                }

                Log.Publish(MessageLevel.Info, "Security Login Failed", "Attempting an integrated security login failed", "Challenge did not match. Potential man in the middle attack.");
                return(false);
            }
        }
Beispiel #11
0
        public static int Main(string[] args)
        {
            if (args.Length < 6)
            {
                Help();
                return(-1);
            }

            int port;

            if (!Int32.TryParse(args[0], out port))
            {
                Console.WriteLine("Got bad port number for arg 1");
                return(-2);
            }

            Guid authGuid;

            if (!Guid.TryParse(args[1], out authGuid))
            {
                Console.WriteLine("Got bad auth guid for arg 2");
                return(-3);
            }

            var addrs = Dns.GetHostAddresses(args[2]);

            if (addrs.Length == 0)
            {
                Console.WriteLine("Cannot connect back to VisualStudio machine");
                return(-4);
            }

            string curDir     = args[3];
            string projectDir = args[4];
            string exe        = args[5];

            if (!File.Exists(exe))
            {
                Console.WriteLine("{0} does not exist, please install the Python interpreter or update the project debug settings to point at the correct interpreter.", exe);
            }

            Guid             launchId    = Guid.NewGuid();
            ManualResetEvent launchEvent = new ManualResetEvent(false);

#pragma warning disable 618 // Handle is obsolete but we need it.
            string msVsMonArgs = "/__dbgautolaunch 0x" + launchEvent.Handle.ToString("X") + " 0x" + Process.GetCurrentProcess().Id.ToString("X") +
                                 " /name " + launchId.ToString() +
                                 " /timeout:600";
#pragma warning restore 618

            Process msvsmonProc;
            try {
                var procStartInfo = new ProcessStartInfo(
                    Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "msvsmon.exe"),
                    msVsMonArgs);

                procStartInfo.UseShellExecute = false;
                msvsmonProc = Process.Start(procStartInfo);
            } catch (Exception e) {
                Console.WriteLine("Failed to start " + Path.Combine(Assembly.GetExecutingAssembly().Location, "msvsmon.exe"));
                Console.WriteLine(e);
                return(-7);
            }

            var processEvent = new ManualResetEvent(true);
            processEvent.SafeWaitHandle = new SafeWaitHandle(msvsmonProc.Handle, false);

            if (WaitHandle.WaitAny(new[] { launchEvent, processEvent }) != 0)
            {
                Console.WriteLine("Failed to initialize msvsmon");
                return(-5);
            }

            try {
                using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP)) {
                    socket.Blocking = true;
                    socket.Connect(new IPEndPoint(addrs[0], port));

                    var secureStream = new NegotiateStream(new NetworkStream(socket, false), true);
                    secureStream.AuthenticateAsClient();

                    var writer = new StreamWriter(secureStream);

                    writer.WriteLine(authGuid.ToString());
                    writer.WriteLine(exe);
                    writer.WriteLine(curDir);
                    writer.WriteLine(projectDir);
                    writer.WriteLine(String.Join(" ", args, 6, args.Length - 6));
                    writer.WriteLine(launchId + "@" + Environment.MachineName);
                    writer.Flush();

                    var reader = new StreamReader(secureStream);
                    var procId = reader.ReadLine();

                    var processId = Int32.Parse(procId);
                    if (processId != 0)
                    {
                        var debuggee = Process.GetProcessById(processId);
                        debuggee.WaitForExit();
                        msvsmonProc.WaitForExit();
                    }
                    else
                    {
                        int    errorLen  = Int32.Parse(reader.ReadLine());
                        char[] buffer    = new char[errorLen];
                        int    bytesRead = reader.Read(buffer, 0, buffer.Length);
                        Console.WriteLine("failed to get process to debug: {0}", new string(buffer, 0, bytesRead));
                        return(-6);
                    }
                }
            } catch (SocketException) {
                Console.WriteLine("Failed to connect back to Visual Studio process.");
                msvsmonProc.Kill();
                return(-8);
            }

            GC.KeepAlive(launchEvent);
            GC.KeepAlive(msvsmonProc);

            return(0);
        }
Beispiel #12
0
        public static void Main()
        {
            NegotiateStream negotiateStream = null;

            try
            {
                // Set the TcpListener on port 13000.
                Int32     port      = 13000;
                IPAddress localAddr = IPAddress.Loopback;

                // TcpListener server = new TcpListener(port);
                TcpListener server = new TcpListener(localAddr, port);

                // Start listening for client requests.
                server.Start();

                // Buffer for reading data
                Byte[] bytes = new Byte[256];
                String data  = null;

                // Enter the listening loop.
                while (true)
                {
                    Console.Write("Waiting for a connection... ");

                    // Perform a blocking call to accept requests.
                    // You could also user server.AcceptSocket() here.
                    TcpClient client = server.AcceptTcpClient();
                    Console.WriteLine("Connected!");

                    data = null;

                    // Get a stream object for reading and writing
                    // Wrap it in a NegotiateStream.
                    negotiateStream = new NegotiateStream(client.GetStream());
                    negotiateStream.AuthenticateAsServer();

                    if (negotiateStream.IsAuthenticated)
                    {
                        Console.WriteLine(
                            "IsAuthenticated: {0}",
                            negotiateStream.IsAuthenticated);
                        Console.WriteLine(
                            "IsMutuallyAuthenticated: {0}",
                            negotiateStream.IsMutuallyAuthenticated);
                        Console.WriteLine(
                            "IsEncrypted: {0}",
                            negotiateStream.IsEncrypted);
                        Console.WriteLine(
                            "IsSigned: {0}",
                            negotiateStream.IsSigned);
                        Console.WriteLine(
                            "IsServer: {0}",
                            negotiateStream.IsServer);
                        IIdentity remoteIdentity =
                            negotiateStream.RemoteIdentity;
                        Console.WriteLine(
                            "Client identity: {0}",
                            remoteIdentity.Name);
                        Console.WriteLine(
                            "Authentication Type: {0}",
                            remoteIdentity.AuthenticationType);
                    }

                    int i;

                    // Loop to receive all the data sent by the client.
                    while (
                        (i = negotiateStream.Read(bytes, 0, bytes.Length))
                        != 0)
                    {
                        // Translate data bytes to a string.
                        // The encoding used is application specific.
                        data =
                            System.Text.Encoding.ASCII.GetString(bytes, 0, i);
                        Console.WriteLine("Received: {0}", data);

                        // Process the data sent by the client.
                        data = data.ToUpper(
                            System.Globalization.CultureInfo.CurrentCulture);

                        byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);

                        // Send back a response.
                        negotiateStream.Write(msg, 0, msg.Length);
                        Console.WriteLine("Sent: {0}", data);
                    }
                }
            }
            catch (AuthenticationException ex)
            {
                Console.WriteLine(ex.Message);
            }
            catch (SocketException ex)
            {
                Console.WriteLine(ex.Message);
            }
            catch (IOException ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                if (negotiateStream != null)
                {
                    negotiateStream.Close();
                }
            }

            Console.WriteLine("\nHit enter to continue...");
            Console.Read();
        }
Beispiel #13
0
        internal static bool TryOpenChannel(NetworkPath netPath, int timeoutInMs, out TcpClientChannel channel, out NetworkTransportException networkEx)
        {
            channel   = null;
            networkEx = null;
            Exception       ex              = null;
            Socket          socket          = null;
            Stream          stream          = null;
            NegotiateStream negotiateStream = null;
            Stopwatch       stopwatch       = new Stopwatch();

            stopwatch.Start();
            try
            {
                socket = new Socket(netPath.TargetEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                if (netPath.Purpose == NetworkPath.ConnectionPurpose.Seeding)
                {
                    socket.ReceiveBufferSize = Parameters.CurrentValues.SeedingNetworkTransferSize;
                    socket.SendBufferSize    = Parameters.CurrentValues.SeedingNetworkTransferSize;
                }
                else
                {
                    socket.ReceiveBufferSize = Parameters.CurrentValues.LogCopyNetworkTransferSize;
                    socket.SendBufferSize    = Parameters.CurrentValues.LogCopyNetworkTransferSize;
                }
                if (netPath.HasSourceEndpoint())
                {
                    socket.Bind(netPath.SourceEndPoint);
                }
                TcpClientChannel.ConnectAbandon connectAbandon = new TcpClientChannel.ConnectAbandon(socket);
                IAsyncResult asyncResult = socket.BeginConnect(netPath.TargetEndPoint.Address, netPath.TargetEndPoint.Port, null, connectAbandon);
                if (!asyncResult.AsyncWaitHandle.WaitOne(timeoutInMs, false))
                {
                    socket = null;
                    connectAbandon.Cancel(asyncResult);
                    TcpChannel.ThrowTimeoutException(netPath.TargetNodeName, Strings.NetworkConnectionTimeout(timeoutInMs / 1000));
                }
                socket.EndConnect(asyncResult);
                long elapsedMilliseconds = stopwatch.ElapsedMilliseconds;
                ExTraceGlobals.TcpClientTracer.TraceDebug <long>(0L, "Connection took {0}ms", elapsedMilliseconds);
                socket.LingerState = new LingerOption(true, 0);
                if (!netPath.UseSocketStream || Parameters.CurrentValues.DisableSocketStream)
                {
                    stream = new NetworkStream(socket, false);
                }
                else
                {
                    stream = new SocketStream(socket, netPath.SocketStreamBufferPool, netPath.SocketStreamAsyncArgPool, netPath.SocketStreamPerfCounters);
                }
                negotiateStream     = new NegotiateStream(stream, false);
                stream              = null;
                elapsedMilliseconds = stopwatch.ElapsedMilliseconds;
                if (elapsedMilliseconds >= (long)timeoutInMs)
                {
                    TcpChannel.ThrowTimeoutException(netPath.TargetNodeName, Strings.NetworkConnectionTimeout(timeoutInMs / 1000));
                }
                int num = timeoutInMs - (int)elapsedMilliseconds;
                negotiateStream.WriteTimeout = num;
                negotiateStream.ReadTimeout  = num;
                TcpClientChannel.AuthAbandon authAbandon = new TcpClientChannel.AuthAbandon(socket, negotiateStream);
                string targetName;
                if (netPath.UseNullSpn)
                {
                    targetName = "";
                }
                else
                {
                    targetName = "HOST/" + netPath.TargetNodeName;
                }
                bool            encrypt = netPath.Encrypt;
                ProtectionLevel protectionLevel;
                if (encrypt)
                {
                    protectionLevel = ProtectionLevel.EncryptAndSign;
                }
                else if (Parameters.CurrentValues.DisableNetworkSigning)
                {
                    protectionLevel = ProtectionLevel.None;
                }
                else
                {
                    protectionLevel = ProtectionLevel.Sign;
                }
                asyncResult = negotiateStream.BeginAuthenticateAsClient(CredentialCache.DefaultNetworkCredentials, targetName, protectionLevel, TokenImpersonationLevel.Identification, null, authAbandon);
                if (!asyncResult.AsyncWaitHandle.WaitOne(num, false))
                {
                    negotiateStream = null;
                    socket          = null;
                    authAbandon.Abandon(asyncResult);
                    TcpChannel.ThrowTimeoutException(netPath.TargetNodeName, Strings.NetworkConnectionTimeout(timeoutInMs / 1000));
                }
                negotiateStream.EndAuthenticateAsClient(asyncResult);
                bool flag = false;
                if (!negotiateStream.IsAuthenticated)
                {
                    flag = true;
                }
                else if (protectionLevel != ProtectionLevel.None && !negotiateStream.IsMutuallyAuthenticated)
                {
                    if (netPath.IgnoreMutualAuth || MachineName.Comparer.Equals(netPath.TargetNodeName, Environment.MachineName))
                    {
                        ExTraceGlobals.TcpClientTracer.TraceDebug(0L, "Ignoring mutual auth since we are local");
                    }
                    else
                    {
                        flag = true;
                    }
                }
                if (!flag && encrypt && !negotiateStream.IsEncrypted)
                {
                    ExTraceGlobals.TcpClientTracer.TraceError(0L, "Encryption requested, but could not be negotiated");
                    flag = true;
                }
                if (flag)
                {
                    ExTraceGlobals.TcpClientTracer.TraceError <bool, bool, bool>(0L, "Security Negotiation failed. Auth={0},MAuth={1},Encrypt={2}", negotiateStream.IsAuthenticated, negotiateStream.IsMutuallyAuthenticated, negotiateStream.IsEncrypted);
                    throw new NetworkCommunicationException(netPath.TargetNodeName, Strings.NetworkSecurityFailed);
                }
                ExTraceGlobals.TcpClientTracer.TraceDebug <long, bool, ProtectionLevel>(0L, "Authenticated Connection took {0}ms. Encrypt={1} ProtRequested={2}", stopwatch.ElapsedMilliseconds, negotiateStream.IsEncrypted, protectionLevel);
                channel = new TcpClientChannel(netPath.TargetNodeName, socket, negotiateStream, timeoutInMs);
                return(true);
            }
            catch (SocketException ex2)
            {
                ex = ex2;
            }
            catch (IOException ex3)
            {
                ex = ex3;
            }
            catch (AuthenticationException ex4)
            {
                ex = ex4;
            }
            catch (NetworkTransportException ex5)
            {
                ex = ex5;
            }
            finally
            {
                if (channel == null)
                {
                    if (negotiateStream != null)
                    {
                        negotiateStream.Dispose();
                    }
                    else if (stream != null)
                    {
                        stream.Dispose();
                    }
                    if (socket != null)
                    {
                        socket.Close();
                    }
                }
                else
                {
                    ReplayCrimsonEvents.NetworkConnectionSuccess.Log <string, IPEndPoint, IPEndPoint>(netPath.TargetNodeName, netPath.TargetEndPoint, channel.LocalEndpoint);
                }
            }
            ExTraceGlobals.TcpClientTracer.TraceError <Exception>(0L, "TryOpenChannel failed. Ex={0}", ex);
            ReplayCrimsonEvents.NetworkConnectionFailure.Log <string, IPEndPoint, IPEndPoint, string>(netPath.TargetNodeName, netPath.TargetEndPoint, netPath.SourceEndPoint, ex.ToString());
            if (ex is NetworkTransportException)
            {
                networkEx = (NetworkTransportException)ex;
            }
            else
            {
                networkEx = new NetworkCommunicationException(netPath.TargetNodeName, ex.Message, ex);
            }
            return(false);
        }
Beispiel #14
0
 public AuthAbandon(Socket socket, NegotiateStream stream)
 {
     this.m_connection = socket;
     this.m_authStream = stream;
 }
Beispiel #15
0
 protected TcpClientChannel(string serverNodeName, Socket channel, NegotiateStream s, int timeout) : base(channel, s, timeout)
 {
     base.PartnerNodeName = serverNodeName;
 }
Beispiel #16
0
 protected override Task AuthenticateAsServerAsync(NegotiateStream server) =>
 Task.Factory.FromAsync(server.BeginAuthenticateAsServer, server.EndAuthenticateAsServer, null);
 protected abstract Task AuthenticateAsServerAsync(NegotiateStream server);
        private async Task VerifyAuthentication(NetworkCredential credential)
        {
            string serverName = Configuration.Security.NegotiateServer.Host;
            int port = Configuration.Security.NegotiateServer.Port;
            string serverSPN = "HOST/" + serverName;
            bool isLocalhost = await IsLocalHost(serverName);
            
            string expectedAuthenticationType = "Kerberos";
            bool mutualAuthenitcated = true;

            if (credential == CredentialCache.DefaultNetworkCredentials && isLocalhost)
            {
                expectedAuthenticationType = "NTLM";
            }
            else if (credential != CredentialCache.DefaultNetworkCredentials && 
                (string.IsNullOrEmpty(credential.UserName) || string.IsNullOrEmpty(credential.Password)))
            {
                // Anonymous authentication.
                expectedAuthenticationType = "NTLM";
                mutualAuthenitcated = false;
            }

            using (var client = new TcpClient())
            {
                await client.ConnectAsync(serverName, port);

                NetworkStream clientStream = client.GetStream();
                using (var auth = new NegotiateStream(clientStream, leaveInnerStreamOpen:false))
                {
                    await auth.AuthenticateAsClientAsync(
                        credential,
                        serverSPN,
                        ProtectionLevel.EncryptAndSign,
                        System.Security.Principal.TokenImpersonationLevel.Identification);

                    Assert.Equal(expectedAuthenticationType, auth.RemoteIdentity.AuthenticationType);
                    Assert.Equal(serverSPN, auth.RemoteIdentity.Name);

                    Assert.Equal(true, auth.IsAuthenticated);
                    Assert.Equal(true, auth.IsEncrypted);
                    Assert.Equal(mutualAuthenitcated, auth.IsMutuallyAuthenticated);
                    Assert.Equal(true, auth.IsSigned);

                    // Send a message to the server. Encode the test data into a byte array.
                    byte[] message = Encoding.UTF8.GetBytes("Hello from the client.");
                    await auth.WriteAsync(message, 0, message.Length);
                }
            }
        }
 protected override Task AuthenticateAsServerAsync(NegotiateStream server) =>
     Task.Run(() => server.AuthenticateAsServerAsync());
        /// <summary>
        /// Authenticates the client using the supplied stream.
        /// </summary>
        /// <param name="stream">the stream to use to authenticate the connection.</param>
        /// <param name="additionalChallenge">Additional data that much match between the client and server
        /// for the connection to succeed.</param>
        /// <returns>
        /// True if authentication succeded, false otherwise.
        /// </returns>
        public bool TryAuthenticateAsClient(Stream stream, byte[] additionalChallenge = null)
        {
            if (additionalChallenge is null)
            {
                additionalChallenge = new byte[] { }
            }
            ;
            if (additionalChallenge.Length > short.MaxValue)
            {
                throw new ArgumentOutOfRangeException("additionalChallenge", "Must be less than 32767 bytes");
            }

            using (NegotiateStream negotiateStream = new NegotiateStream(stream, true))
            {
                try
                {
                    negotiateStream.AuthenticateAsClient(m_credentials, string.Empty, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification);
                }
                catch (Exception ex)
                {
                    Log.Publish(MessageLevel.Info, "Security Login Failed", "Attempting an integrated security login failed", null, ex);
                    return(false);
                }

                //Exchange the challenge data.
                //Since NegotiateStream is already a trusted stream
                //Simply writing the raw is as secure as creating a challenge response
                negotiateStream.Write((short)additionalChallenge.Length);
                if (additionalChallenge.Length > 0)
                {
                    negotiateStream.Write(additionalChallenge);
                }
                negotiateStream.Flush();

                int len = negotiateStream.ReadInt16();
                if (len < 0)
                {
                    Log.Publish(MessageLevel.Info, "Security Login Failed", "Attempting an integrated security login failed", "Challenge Length is invalid: " + len.ToString());
                    return(false);
                }

                byte[] remoteChallenge;
                if (len == 0)
                {
                    remoteChallenge = new byte[0];
                }
                else
                {
                    remoteChallenge = negotiateStream.ReadBytes(len);
                }

                if (remoteChallenge.SecureEquals(additionalChallenge))
                {
                    return(true);
                }
                else
                {
                    Log.Publish(MessageLevel.Info, "Security Login Failed", "Attempting an integrated security login failed", "Challenge did not match. Potential man in the middle attack.");
                    return(false);
                }
            }
        }
    }
        public void NegotiateStream_StreamToStream_FlushAsync_Propagated()
        {
            VirtualNetwork network = new VirtualNetwork();

            using (var stream = new VirtualNetworkStream(network, isServer: false))
            using (var negotiateStream = new NegotiateStream(stream))
            {
                Task task = negotiateStream.FlushAsync();

                Assert.False(task.IsCompleted);
                stream.CompleteAsyncFlush();
                Assert.True(task.IsCompleted);
            }
        }
 protected abstract Task WriteAsync(NegotiateStream stream, byte[] buffer, int offset, int count, CancellationToken cancellationToken      = default);
Beispiel #23
0
 protected override Task AuthenticateAsServerAsync(NegotiateStream server) =>
 Task.Run(() => server.AuthenticateAsServer(null));
 protected override Task WriteAsync(NegotiateStream stream, byte[] buffer, int offset, int count, CancellationToken cancellationToken) =>
 stream.WriteAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask();
Beispiel #25
0
 protected override Task AuthenticateAsServerAsync(NegotiateStream server) =>
 Task.Run(() => server.AuthenticateAsServer((NetworkCredential)CredentialCache.DefaultCredentials, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification));
 protected override Task AuthenticateAsClientAsync(NegotiateStream client, NetworkCredential credential, string targetName) =>
 client.AuthenticateAsClientAsync(credential, targetName, ProtectionLevel.None, TokenImpersonationLevel.Identification);
Beispiel #27
0
 protected abstract Task AuthenticateAsClientAsync(NegotiateStream client, NetworkCredential credential, string targetName);
 protected override Task AuthenticateAsServerAsync(NegotiateStream server) =>
 server.AuthenticateAsServerAsync(CredentialCache.DefaultNetworkCredentials, ProtectionLevel.None, TokenImpersonationLevel.Identification);
Beispiel #29
0
 protected override Task AuthenticateAsClientAsync(NegotiateStream client, NetworkCredential credential, string targetName) =>
 client.AuthenticateAsClientAsync(credential, targetName);
 protected override Task WriteAsync(NegotiateStream stream, byte[] buffer, int offset, int count, CancellationToken cancellationToken) =>
 Task.Factory.FromAsync(stream.BeginWrite, stream.EndWrite, buffer, offset, count, null);
Beispiel #31
0
 protected override Task AuthenticateAsClientAsync(NegotiateStream client, NetworkCredential credential, string targetName) =>
 Task.Factory.FromAsync(client.BeginAuthenticateAsClient, client.EndAuthenticateAsClient, credential, targetName, null);
 protected override Task AuthenticateAsServerAsync(NegotiateStream server) =>
 Task.Factory.FromAsync(server.BeginAuthenticateAsServer, server.EndAuthenticateAsServer, (ExtendedProtectionPolicy)null, null);
 protected abstract Task AuthenticateAsClientAsync(NegotiateStream client, NetworkCredential credential, string targetName);
 protected override Task AuthenticateAsClientAsync(NegotiateStream client, NetworkCredential credential, string targetName) =>
 Task.Factory.FromAsync(
     (callback, state) => client.BeginAuthenticateAsClient(credential, targetName, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification, callback, state),
     client.EndAuthenticateAsClient, null);
 protected override Task AuthenticateAsClientAsync(NegotiateStream client, NetworkCredential credential, string targetName) =>
     Task.Factory.FromAsync(client.BeginAuthenticateAsClient, client.EndAuthenticateAsClient, credential, targetName, null);
 protected override Task AuthenticateAsServerAsync(NegotiateStream server) =>
 Task.Factory.FromAsync(
     (callback, state) => server.BeginAuthenticateAsServer((NetworkCredential)CredentialCache.DefaultCredentials, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification, callback, state),
     server.EndAuthenticateAsServer, null);
 protected override Task AuthenticateAsClientAsync(NegotiateStream client, NetworkCredential credential, string targetName) =>
     Task.Run(() => client.AuthenticateAsClient(credential, targetName));
 protected override Task <int> ReadAsync(NegotiateStream stream, byte[] buffer, int offset, int count, CancellationToken cancellationToken) =>
 Task.FromResult(stream.Read(buffer, offset, count));
        public void NegotiateStream_StreamToStream_Authentication_EmptyCredentials_Fails()
        {
            string targetName = "testTargetName";

            // Ensure there is no confusion between DefaultCredentials / DefaultNetworkCredentials and a
            // NetworkCredential object with empty user, password and domain.
            NetworkCredential emptyNetworkCredential = new NetworkCredential("", "", "");
            Assert.NotEqual(emptyNetworkCredential, CredentialCache.DefaultCredentials);
            Assert.NotEqual(emptyNetworkCredential, CredentialCache.DefaultNetworkCredentials);

            VirtualNetwork network = new VirtualNetwork();

            using (var clientStream = new VirtualNetworkStream(network, isServer: false))
            using (var serverStream = new VirtualNetworkStream(network, isServer: true))
            using (var client = new NegotiateStream(clientStream))
            using (var server = new NegotiateStream(serverStream))
            {
                Assert.False(client.IsAuthenticated);
                Assert.False(server.IsAuthenticated);

                Task[] auth = new Task[2];

                auth[0] = client.AuthenticateAsClientAsync(emptyNetworkCredential, targetName);
                auth[1] = server.AuthenticateAsServerAsync();

                bool finished = Task.WaitAll(auth, TestConfiguration.PassingTestTimeoutMilliseconds);
                Assert.True(finished, "Handshake completed in the allotted time");

                // Expected Client property values:
                Assert.True(client.IsAuthenticated);
                Assert.Equal(TokenImpersonationLevel.Identification, client.ImpersonationLevel);
                Assert.Equal(true, client.IsEncrypted);
                Assert.Equal(false, client.IsMutuallyAuthenticated);
                Assert.Equal(false, client.IsServer);
                Assert.Equal(true, client.IsSigned);
                Assert.Equal(false, client.LeaveInnerStreamOpen);

                IIdentity serverIdentity = client.RemoteIdentity;
                Assert.Equal("NTLM", serverIdentity.AuthenticationType);
                Assert.Equal(true, serverIdentity.IsAuthenticated);
                Assert.Equal(targetName, serverIdentity.Name);

                // Expected Server property values:
                Assert.True(server.IsAuthenticated);
                Assert.Equal(TokenImpersonationLevel.Identification, server.ImpersonationLevel);
                Assert.Equal(true, server.IsEncrypted);
                Assert.Equal(false, server.IsMutuallyAuthenticated);
                Assert.Equal(true, server.IsServer);
                Assert.Equal(true, server.IsSigned);
                Assert.Equal(false, server.LeaveInnerStreamOpen);

                IIdentity clientIdentity = server.RemoteIdentity;
                Assert.Equal("NTLM", clientIdentity.AuthenticationType);

                // TODO #5241: Behavior difference:
                Assert.Equal(false, clientIdentity.IsAuthenticated);
                // On .Net Desktop: Assert.Equal(true, clientIdentity.IsAuthenticated);

                IdentityValidator.AssertHasName(clientIdentity, @"NT AUTHORITY\ANONYMOUS LOGON");
            }
        }
 protected override Task WriteAsync(NegotiateStream stream, byte[] buffer, int offset, int count, CancellationToken cancellationToken)
 {
     stream.Write(buffer, offset, count);
     return(Task.CompletedTask);
 }
        protected override async Task <IDuplexPipe> ConnectPipelineAsync(int sendMaxMessageSize, int receiveMaxMessageSize, CancellationToken cancellationToken)
        {
            // TODO: Implement cancellationToken somehow, but how?. ConnectAsync and AuthenticateAsClientAsync don't accept a CancellationToken.
            IDuplexPipe?connection;

            var    endPoint            = this.CreateNetEndPoint();
            Stream?authenticatedStream = null;
            Stream?workStream          = null;

            var sendOptions = new PipeOptions(
                pauseWriterThreshold: sendMaxMessageSize * 2, resumeWriterThreshold: sendMaxMessageSize,
                readerScheduler: PipeScheduler.ThreadPool,
                useSynchronizationContext: false);
            var receiveOptions = new PipeOptions(
                pauseWriterThreshold: receiveMaxMessageSize * 2, resumeWriterThreshold: receiveMaxMessageSize,
                readerScheduler: PipeScheduler.Inline,
                useSynchronizationContext: false);

            try
            {
                Socket?socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                try
                {
                    SetRecommendedClientOptions(socket);

                    string sslHost;
                    switch (endPoint)
                    {
                    case IPEndPoint ipEndPoint:
#if PLAT_CONNECT_CANCELLATION
                        await socket.ConnectAsync(ipEndPoint.Address, ipEndPoint.Port, cancellationToken).ContextFree();
#else
                        await socket.ConnectAsync(ipEndPoint.Address, ipEndPoint.Port).ContextFree();
#endif
                        sslHost = ipEndPoint.Address.ToString();
                        break;

                    case DnsEndPoint dnsEndPoint:
#if PLAT_CONNECT_CANCELLATION
                        await socket.ConnectAsync(dnsEndPoint.Host, dnsEndPoint.Port, cancellationToken).ContextFree();
#else
                        await socket.ConnectAsync(dnsEndPoint.Host, dnsEndPoint.Port).ContextFree();
#endif

                        sslHost = dnsEndPoint.Host;
                        break;

                    default:
                        throw new NotSupportedException($"Unsupported end point '{endPoint}',");
                    }

                    workStream = new NetworkStream(socket, true);
                    socket     = null; // Prevent closing, NetworkStream has taken ownership

                    var selectedAuthentication = await this.GetAuthenticationOptionsAsync(workStream, cancellationToken).ContextFree();

                    if (selectedAuthentication is SslClientOptions sslOptions)
                    {
                        var sslStream = new SslStream(workStream, false,
                                                      sslOptions.RemoteCertificateValidationCallback,
                                                      sslOptions.LocalCertificateSelectionCallback,
                                                      sslOptions.EncryptionPolicy);

                        workStream = authenticatedStream = sslStream;

#if PLAT_CONNECT_CANCELLATION
                        var authOptions = new SslClientAuthenticationOptions()
                        {
                            TargetHost                     = sslHost,
                            ClientCertificates             = sslOptions.ClientCertificates,
                            EnabledSslProtocols            = sslOptions.EnabledSslProtocols,
                            CertificateRevocationCheckMode = sslOptions.CertificateRevocationCheckMode
                        };

                        await sslStream.AuthenticateAsClientAsync(authOptions, cancellationToken).ContextFree();
#else
                        await sslStream.AuthenticateAsClientAsync(sslHost, sslOptions.ClientCertificates, sslOptions.EnabledSslProtocols,
                                                                  sslOptions.CertificateRevocationCheckMode != X509RevocationMode.NoCheck).ContextFree();
#endif
                    }
                    else if (selectedAuthentication is NegotiateClientOptions negotiateOptions)
                    {
                        var negotiateStream = new NegotiateStream(workStream, false);
                        workStream = authenticatedStream = negotiateStream;

                        await negotiateStream.AuthenticateAsClientAsync(
                            negotiateOptions !.Credential ?? CredentialCache.DefaultNetworkCredentials,
                            negotiateOptions.TargetName ?? "").ContextFree();
                    }
                    else if (selectedAuthentication is AnonymousAuthenticationClientOptions)
                    {
                        authenticatedStream = workStream;
                    }
                    else
                    {
                        throw new NotSupportedException("Authentication options not supported.");
                    }

                    connection = new StreamDuplexPipe(authenticatedStream);//, sendOptions, receiveOptions);
                }
                finally
                {
                    socket?.Dispose();
                }

                this.authenticatedStream = authenticatedStream as AuthenticatedStream;
                workStream = null;

                return(connection);
            }
            finally
            {
                workStream?.Dispose();
            }
        }
        public void NegotiateStream_StreamToStream_Flush_Propagated()
        {
            VirtualNetwork network = new VirtualNetwork();

            using (var stream = new VirtualNetworkStream(network, isServer: false))
            using (var negotiateStream = new NegotiateStream(stream))
            {
                Assert.False(stream.HasBeenSyncFlushed);
                negotiateStream.Flush();
                Assert.True(stream.HasBeenSyncFlushed);
            }
        }