Exemplo n.º 1
0
        /// <summary>
        ///  Receives and processes remote requests to establish secure channels
        /// </summary>
        /// <param name="threadParameter">A dictionary whose key is the machine name and the
        /// value is the machine password</param>
        internal static void EstablishSecureChannel(object threadParameter)
        {
            Dictionary <string, string> machineNameToPasswordDictionary =
                threadParameter as Dictionary <string, string>;

            if (serverForSecureChannel == null)
            {
                serverForSecureChannel = new NrpcServer(null);
                serverForSecureChannel.StartTcp(tcpPort);
                //todo: support ipv6
                serverForSecureChannel.StartNamedPipe(NrpcUtility.NETLOGON_RPC_OVER_NP_WELLKNOWN_ENDPOINT, null, IPAddress.Any);
            }

            TimeSpan defaultTimeSpan = new TimeSpan(0, 0, 0, 0, DefaultTimeout);
            NrpcServerSessionContext sessionContext;

            while (!isStopped)
            {
                NrpcRequestStub request = serverForSecureChannel.ExpectRpcCall <NrpcRequestStub>(defaultTimeSpan, out sessionContext);
                switch (request.Opnum)
                {
                case NrpcMethodOpnums.NetrServerReqChallenge:
                    NrpcNetrServerReqChallengeRequest nrpcNetrServerReqChallengeRequest =
                        request as NrpcNetrServerReqChallengeRequest;
                    NrpcNetrServerReqChallengeResponse nrpcNetrServerReqChallengeResponse;

                    if (!machineNameToPasswordDictionary.ContainsKey(sessionContext.ClientComputerName))
                    {
                        nrpcNetrServerReqChallengeResponse =
                            serverForSecureChannel.CreateNetrServerReqChallengeResponse(sessionContext,
                                                                                        NrpcUtility.GenerateNonce(8), "");
                        nrpcNetrServerReqChallengeResponse.Status = NtStatus.STATUS_ACCESS_DENIED;
                    }
                    else
                    {
                        nrpcNetrServerReqChallengeResponse =
                            serverForSecureChannel.CreateNetrServerReqChallengeResponse(sessionContext,
                                                                                        NrpcUtility.GenerateNonce(8),
                                                                                        machineNameToPasswordDictionary[sessionContext.ClientComputerName]);
                    }
                    serverForSecureChannel.SendRpcCallResponse(
                        sessionContext, nrpcNetrServerReqChallengeResponse);
                    break;

                case NrpcMethodOpnums.NetrServerAuthenticate:
                    NrpcNetrServerAuthenticateRequest nrpcNetrServerAuthenticateRequest =
                        request as NrpcNetrServerAuthenticateRequest;
                    NrpcNetrServerAuthenticateResponse nrpcNetrServerAuthenticateResponse =
                        serverForSecureChannel.CreateNetrServerAuthenticateResponse(sessionContext);

                    serverForSecureChannel.SendRpcCallResponse(
                        sessionContext, nrpcNetrServerAuthenticateResponse);
                    break;

                case NrpcMethodOpnums.NetrServerAuthenticate2:
                    NrpcNetrServerAuthenticate2Request nrpcNetrServerAuthenticate2Request =
                        request as NrpcNetrServerAuthenticate2Request;
                    NrpcNetrServerAuthenticate2Response nrpcNetrServerAuthenticate2Response =
                        serverForSecureChannel.CreateNetrServerAuthenticate2Response(sessionContext,
                                                                                     (uint)sessionContext.NegotiateFlags);

                    serverForSecureChannel.SendRpcCallResponse(
                        sessionContext, nrpcNetrServerAuthenticate2Response);
                    break;

                case NrpcMethodOpnums.NetrServerAuthenticate3:
                    NrpcNetrServerAuthenticate3Request nrpcNetrServerAuthenticate3Request =
                        request as NrpcNetrServerAuthenticate3Request;
                    NrpcNetrServerAuthenticate3Response nrpcNetrServerAuthenticate3Response =
                        serverForSecureChannel.CreateNetrServerAuthenticate3Response(sessionContext,
                                                                                     (uint)sessionContext.NegotiateFlags, 100);

                    serverForSecureChannel.SendRpcCallResponse(
                        sessionContext, nrpcNetrServerAuthenticate3Response);
                    break;

                default:
                    //bypass other requests
                    break;
                }
            }

            serverForSecureChannel.StopTcp(tcpPort);
            serverForSecureChannel.StopNamedPipe(NrpcUtility.NETLOGON_RPC_OVER_NP_WELLKNOWN_ENDPOINT);
            serverForSecureChannel.Dispose();
            serverForSecureChannel = null;
        }
Exemplo n.º 2
0
        internal void UpdateSessionContextWithMessageSent(NrpcResponseStub messageToSend)
        {
            NrpcClientSessionInfo clientSessionInfo;

            switch (messageToSend.Opnum)
            {
            case NrpcMethodOpnums.NetrServerReqChallenge:
                NrpcNetrServerReqChallengeResponse netrServerReqChallengeResponse =
                    messageToSend as NrpcNetrServerReqChallengeResponse;

                if (netrServerReqChallengeResponse == null)
                {
                    throw new InvalidOperationException("messageToSend doesn't match its MethodOpnums");
                }

                ServerChallenge = netrServerReqChallengeResponse.ServerChallenge.Value.data;
                break;

            case NrpcMethodOpnums.NetrServerAuthenticate:
                NrpcNetrServerAuthenticateResponse netrServerAuthenticateResponse =
                    (messageToSend as NrpcNetrServerAuthenticateResponse);

                if (netrServerAuthenticateResponse == null)
                {
                    throw new InvalidOperationException("messageToSend doesn't match its MethodOpnums");
                }

                //if authentication is successfully finished, store the secure channel to the session table
                if (netrServerAuthenticateResponse.Status == NtStatus.STATUS_SUCCESS)
                {
                    clientSessionInfo.ComputerName           = ClientComputerName;
                    clientSessionInfo.AccountRid             = AccountRid;
                    clientSessionInfo.NegotiateFlags         = NegotiateFlags;
                    clientSessionInfo.SecureChannelType      = SecureChannelType;
                    clientSessionInfo.ServerStoredCredential = StoredCredential;
                    clientSessionInfo.SessionKey             = SessionKey;
                    clientSessionInfo.SharedSecret           = SharedSecret;
                    clientSessionInfo.ClientSequenceNumber   = null;
                    clientSessionInfo.ServerSequenceNumber   = null;

                    //if this client computer already established a secure channel, remove it first
                    if (clientSessionInfoTable.ContainsKey(ClientComputerName))
                    {
                        clientSessionInfoTable.Remove(ClientComputerName);
                    }

                    clientSessionInfoTable[ClientComputerName] = clientSessionInfo;
                }
                break;

            case NrpcMethodOpnums.NetrServerAuthenticate2:
                NrpcNetrServerAuthenticate2Response netrServerAuthenticate2Response =
                    (messageToSend as NrpcNetrServerAuthenticate2Response);

                if (netrServerAuthenticate2Response == null)
                {
                    throw new InvalidOperationException("messageToSend doesn't match its MethodOpnums");
                }

                NegotiateFlags = (NrpcNegotiateFlags)netrServerAuthenticate2Response.NegotiateFlags;

                //if authentication is successfully finished, store the secure channel to the session table
                if (netrServerAuthenticate2Response.Status == NtStatus.STATUS_SUCCESS)
                {
                    clientSessionInfo.ComputerName           = ClientComputerName;
                    clientSessionInfo.AccountRid             = AccountRid;
                    clientSessionInfo.NegotiateFlags         = NegotiateFlags;
                    clientSessionInfo.SecureChannelType      = SecureChannelType;
                    clientSessionInfo.ServerStoredCredential = StoredCredential;
                    clientSessionInfo.SessionKey             = SessionKey;
                    clientSessionInfo.SharedSecret           = SharedSecret;
                    clientSessionInfo.ClientSequenceNumber   = null;
                    clientSessionInfo.ServerSequenceNumber   = null;

                    //if this client computer already established a secure channel, remove it first
                    if (clientSessionInfoTable.ContainsKey(ClientComputerName))
                    {
                        clientSessionInfoTable.Remove(ClientComputerName);
                    }

                    clientSessionInfoTable[ClientComputerName] = clientSessionInfo;
                }
                break;

            case NrpcMethodOpnums.NetrLogonGetCapabilities:
                NrpcNetrLogonGetCapabilitiesResponse nrpcNetrLogonGetCapabilitiesResponse =
                    (messageToSend as NrpcNetrLogonGetCapabilitiesResponse);

                if (nrpcNetrLogonGetCapabilitiesResponse == null)
                {
                    throw new InvalidOperationException("messageToSend doesn't match its MethodOpnums");
                }

                NegotiateFlags =
                    (NrpcNegotiateFlags)nrpcNetrLogonGetCapabilitiesResponse.ServerCapabilities.Value.ServerCapabilities;
                break;

            case NrpcMethodOpnums.NetrServerAuthenticate3:
                NrpcNetrServerAuthenticate3Response netrServerAuthenticate3Response =
                    (messageToSend as NrpcNetrServerAuthenticate3Response);

                if (netrServerAuthenticate3Response == null)
                {
                    throw new InvalidOperationException("messageToSend doesn't match its MethodOpnums");
                }

                NegotiateFlags = (NrpcNegotiateFlags)netrServerAuthenticate3Response.NegotiateFlags;
                if (netrServerAuthenticate3Response.AccountRid.HasValue)
                {
                    AccountRid = netrServerAuthenticate3Response.AccountRid.Value;
                }
                //if authentication is successfully finished, store the secure channel to the session table
                if (netrServerAuthenticate3Response.Status == NtStatus.STATUS_SUCCESS)
                {
                    clientSessionInfo.ComputerName           = ClientComputerName;
                    clientSessionInfo.AccountRid             = AccountRid;
                    clientSessionInfo.NegotiateFlags         = NegotiateFlags;
                    clientSessionInfo.SecureChannelType      = SecureChannelType;
                    clientSessionInfo.ServerStoredCredential = StoredCredential;
                    clientSessionInfo.SessionKey             = SessionKey;
                    clientSessionInfo.SharedSecret           = SharedSecret;
                    clientSessionInfo.ClientSequenceNumber   = null;
                    clientSessionInfo.ServerSequenceNumber   = null;

                    //if this client computer already established a secure channel, remove it first
                    if (clientSessionInfoTable.ContainsKey(ClientComputerName))
                    {
                        clientSessionInfoTable.Remove(ClientComputerName);
                    }

                    clientSessionInfoTable[ClientComputerName] = clientSessionInfo;
                }
                break;

            default:
                break;
            }
        }