/// <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; }
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; } }