예제 #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;
        }
예제 #2
0
        internal void UpdateSessionContextWithMessageReceived(NrpcRequestStub messageReceived)
        {
            requestReceived = messageReceived;

            switch (messageReceived.Opnum)
            {
            case NrpcMethodOpnums.NetrLogonSamLogon:
                CheckForSecureChannel();
                NrpcNetrLogonSamLogonRequest nrpcNetrLogonSamLogonRequest =
                    messageReceived as NrpcNetrLogonSamLogonRequest;

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

                ValidateNetlogonAuthenticator(nrpcNetrLogonSamLogonRequest.Authenticator);
                break;

            case NrpcMethodOpnums.NetrLogonSamLogoff:
                CheckForSecureChannel();
                NrpcNetrLogonSamLogoffRequest nrpcNetrLogonSamLogoffRequest =
                    messageReceived as NrpcNetrLogonSamLogoffRequest;

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

                ValidateNetlogonAuthenticator(nrpcNetrLogonSamLogoffRequest.Authenticator);
                break;

            case NrpcMethodOpnums.NetrServerReqChallenge:
                NrpcNetrServerReqChallengeRequest nrpcNetrServerReqChallengeRequest =
                    messageReceived as NrpcNetrServerReqChallengeRequest;

                if (nrpcNetrServerReqChallengeRequest == null)
                {
                    throw new InvalidOperationException("messageReceived doesn't match its MethodOpnums");
                }
                ClientComputerName = nrpcNetrServerReqChallengeRequest.ComputerName;
                ClientChallenge    = nrpcNetrServerReqChallengeRequest.ClientChallenge.Value.data;
                break;

            case NrpcMethodOpnums.NetrServerAuthenticate:
                NrpcNetrServerAuthenticateRequest authenticateRequest =
                    (messageReceived as NrpcNetrServerAuthenticateRequest);

                if (authenticateRequest == null)
                {
                    throw new InvalidOperationException("messageReceived doesn't match its MethodOpnums");
                }
                ClientComputerName = authenticateRequest.ComputerName;
                AccountName        = authenticateRequest.AccountName;
                SecureChannelType  = authenticateRequest.SecureChannelType;
                ComputeSessionKey();
                ValidateClientCredential(SessionKey, (uint)NegotiateFlags, ClientChallenge,
                                         authenticateRequest.ClientCredential);
                break;

            case NrpcMethodOpnums.NetrServerPasswordSet:
                CheckForSecureChannel();
                NrpcNetrServerPasswordSetRequest nrpcNetrServerPasswordSetRequest =
                    messageReceived as NrpcNetrServerPasswordSetRequest;

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

                ValidateNetlogonAuthenticator(nrpcNetrServerPasswordSetRequest.Authenticator);
                break;

            case NrpcMethodOpnums.NetrDatabaseDeltas:
                CheckForSecureChannel();
                NrpcNetrDatabaseDeltasRequest nrpcNetrDatabaseDeltasRequest =
                    messageReceived as NrpcNetrDatabaseDeltasRequest;

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

                ValidateNetlogonAuthenticator(nrpcNetrDatabaseDeltasRequest.Authenticator);
                break;

            case NrpcMethodOpnums.NetrDatabaseSync:
                CheckForSecureChannel();
                NrpcNetrDatabaseSyncRequest nrpcNetrDatabaseSyncRequest =
                    messageReceived as NrpcNetrDatabaseSyncRequest;

                if (nrpcNetrDatabaseSyncRequest == null)
                {
                    throw new InvalidOperationException("messageReceived doesn't match its MethodOpnums");
                }
                ValidateNetlogonAuthenticator(nrpcNetrDatabaseSyncRequest.Authenticator);
                break;

            case NrpcMethodOpnums.NetrAccountDeltas:
                CheckForSecureChannel();
                NrpcNetrAccountDeltasRequest nrpcNetrAccountDeltasRequest =
                    messageReceived as NrpcNetrAccountDeltasRequest;

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

                ValidateNetlogonAuthenticator(nrpcNetrAccountDeltasRequest.Authenticator);
                break;

            case NrpcMethodOpnums.NetrAccountSync:
                CheckForSecureChannel();
                NrpcNetrAccountSyncRequest nrpcNetrAccountSyncRequest =
                    messageReceived as NrpcNetrAccountSyncRequest;

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

                ValidateNetlogonAuthenticator(nrpcNetrAccountSyncRequest.Authenticator);
                break;

            case NrpcMethodOpnums.NetrServerAuthenticate2:
                NrpcNetrServerAuthenticate2Request authenticate2Request =
                    (messageReceived as NrpcNetrServerAuthenticate2Request);

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

                if (authenticate2Request.NegotiateFlags == null)
                {
                    throw new InvalidOperationException("NegotiateFlags in the request isn't present");
                }
                NegotiateFlags     = (NrpcNegotiateFlags)authenticate2Request.NegotiateFlags.Value;
                SecureChannelType  = authenticate2Request.SecureChannelType;
                AccountName        = authenticate2Request.AccountName;
                ClientComputerName = authenticate2Request.ComputerName;

                ComputeSessionKey();
                ValidateClientCredential(SessionKey, (uint)NegotiateFlags, ClientChallenge,
                                         authenticate2Request.ClientCredential);
                break;

            case NrpcMethodOpnums.NetrDatabaseSync2:
                CheckForSecureChannel();
                NrpcNetrDatabaseSync2Request nrpcNetrDatabaseSync2Request =
                    messageReceived as NrpcNetrDatabaseSync2Request;

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

                ValidateNetlogonAuthenticator(nrpcNetrDatabaseSync2Request.Authenticator);
                break;

            case NrpcMethodOpnums.NetrDatabaseRedo:
                CheckForSecureChannel();
                NrpcNetrDatabaseRedoRequest nrpcNetrDatabaseRedoRequest =
                    messageReceived as NrpcNetrDatabaseRedoRequest;

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

                ValidateNetlogonAuthenticator(nrpcNetrDatabaseRedoRequest.Authenticator);
                break;

            case NrpcMethodOpnums.NetrLogonGetCapabilities:
                CheckForSecureChannel();
                NrpcNetrLogonGetCapabilitiesRequest nrpcNetrLogonGetCapabilitiesRequest =
                    messageReceived as NrpcNetrLogonGetCapabilitiesRequest;

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

                ValidateNetlogonAuthenticator(nrpcNetrLogonGetCapabilitiesRequest.Authenticator);
                break;

            case NrpcMethodOpnums.NetrServerAuthenticate3:
                NrpcNetrServerAuthenticate3Request authenticate3Request =
                    messageReceived as NrpcNetrServerAuthenticate3Request;

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

                if (authenticate3Request.NegotiateFlags == null)
                {
                    throw new InvalidOperationException("NegotiateFlags in the request isn't present");
                }
                NegotiateFlags     = (NrpcNegotiateFlags)authenticate3Request.NegotiateFlags.Value;
                ClientComputerName = authenticate3Request.ComputerName;
                SecureChannelType  = authenticate3Request.SecureChannelType;
                AccountName        = authenticate3Request.AccountName;

                ComputeSessionKey();
                ValidateClientCredential(SessionKey, (uint)NegotiateFlags, ClientChallenge,
                                         authenticate3Request.ClientCredential);
                break;

            case NrpcMethodOpnums.NetrLogonGetDomainInfo:
                CheckForSecureChannel();
                NrpcNetrLogonGetDomainInfoRequest nrpcNetrLogonGetDomainInfoRequest =
                    messageReceived as NrpcNetrLogonGetDomainInfoRequest;

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

                ValidateNetlogonAuthenticator(nrpcNetrLogonGetDomainInfoRequest.Authenticator);
                break;

            case NrpcMethodOpnums.NetrServerPasswordSet2:
                CheckForSecureChannel();
                NrpcNetrServerPasswordSet2Request nrpcNetrServerPasswordSet2Request =
                    messageReceived as NrpcNetrServerPasswordSet2Request;

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

                ValidateNetlogonAuthenticator(nrpcNetrServerPasswordSet2Request.Authenticator);
                break;

            case NrpcMethodOpnums.NetrServerPasswordGet:
                CheckForSecureChannel();
                NrpcNetrServerPasswordGetRequest nrpcNetrServerPasswordGetRequest =
                    messageReceived as NrpcNetrServerPasswordGetRequest;

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

                ValidateNetlogonAuthenticator(nrpcNetrServerPasswordGetRequest.Authenticator);
                break;

            case NrpcMethodOpnums.NetrLogonSendToSam:
                CheckForSecureChannel();
                NrpcNetrLogonSendToSamRequest nrpcNetrLogonSendToSamRequest =
                    messageReceived as NrpcNetrLogonSendToSamRequest;

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

                ValidateNetlogonAuthenticator(nrpcNetrLogonSendToSamRequest.Authenticator);
                break;

            case NrpcMethodOpnums.NetrLogonSamLogonEx:
                CheckForSecureChannel();
                break;

            case NrpcMethodOpnums.NetrServerTrustPasswordsGet:
                CheckForSecureChannel();
                NrpcNetrServerTrustPasswordsGetRequest nrpcNetrServerTrustPasswordsGetRequest =
                    messageReceived as NrpcNetrServerTrustPasswordsGetRequest;

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

                ValidateNetlogonAuthenticator(nrpcNetrServerTrustPasswordsGetRequest.Authenticator);
                break;

            case NrpcMethodOpnums.NetrGetForestTrustInformation:
                CheckForSecureChannel();
                NrpcNetrGetForestTrustInformationRequest nrpcNetrGetForestTrustInformationRequest =
                    messageReceived as NrpcNetrGetForestTrustInformationRequest;

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

                ValidateNetlogonAuthenticator(nrpcNetrGetForestTrustInformationRequest.Authenticator);
                break;

            case NrpcMethodOpnums.NetrLogonSamLogonWithFlags:
                CheckForSecureChannel();
                NrpcNetrLogonSamLogonWithFlagsRequest nrpcNetrLogonSamLogonWithFlagsRequest =
                    messageReceived as NrpcNetrLogonSamLogonWithFlagsRequest;

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

                ValidateNetlogonAuthenticator(nrpcNetrLogonSamLogonWithFlagsRequest.Authenticator);
                break;

            case NrpcMethodOpnums.NetrServerGetTrustInfo:
                CheckForSecureChannel();
                NrpcNetrServerGetTrustInfoRequest nrpcNetrServerGetTrustInfoRequest =
                    messageReceived as NrpcNetrServerGetTrustInfoRequest;

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

                ValidateNetlogonAuthenticator(nrpcNetrServerGetTrustInfoRequest.Authenticator);
                break;

            case NrpcMethodOpnums.DsrUpdateReadOnlyServerDnsRecords:
                CheckForSecureChannel();
                NrpcDsrUpdateReadOnlyServerDnsRecordsRequest nrpcDsrUpdateReadOnlyServerDnsRecordsRequest =
                    messageReceived as NrpcDsrUpdateReadOnlyServerDnsRecordsRequest;

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

                ValidateNetlogonAuthenticator(nrpcDsrUpdateReadOnlyServerDnsRecordsRequest.Authenticator);
                break;

            case NrpcMethodOpnums.NetrChainSetClientAttributes:
                CheckForSecureChannel();
                NrpcNetrChainSetClientAttributesRequest nrpcNetrChainSetClientAttributesRequest =
                    messageReceived as NrpcNetrChainSetClientAttributesRequest;

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

                ValidateNetlogonAuthenticator(nrpcNetrChainSetClientAttributesRequest.Authenticator);
                break;

            default:
                break;
            }
        }