Esempio n. 1
0
        bool PassStatelessPoWfilter(ICcpRemoteEndpoint clientEndpoint, ClientHelloPacket0 packet)// packets processor thread // sends responses
        {
            switch (packet.StatelessProofOfWorkType)
            {
            case StatelessProofOfWorkType._2019_06:
                // verify size of PoW data
                if (packet.StatelessProofOfWorkData.Length < 12 || packet.StatelessProofOfWorkData.Length > 64)
                {
                    throw new CcpBadPacketException();
                }

                // verify datetime ("period")
                // return err code if time is wrong, with correct server's UTC time
                uint receivedTimeSec32;

                unsafe
                {
                    fixed(byte *statelessProofOfWorkDataPtr = packet.StatelessProofOfWorkData)
                    {
                        fixed(byte *addressBytesPtr = clientEndpoint.AddressBytes)
                        {
                            receivedTimeSec32 = *((uint *)statelessProofOfWorkDataPtr);
                            if (addressBytesPtr[0] != statelessProofOfWorkDataPtr[4] ||
                                addressBytesPtr[1] != statelessProofOfWorkDataPtr[5] ||
                                addressBytesPtr[2] != statelessProofOfWorkDataPtr[6] ||
                                addressBytesPtr[3] != statelessProofOfWorkDataPtr[7]
                                )
                            {
                                if (_config.RespondErrors)
                                {
                                    RespondToHello0(clientEndpoint, ServerHello0Status.ErrorBadStatelessProofOfWork_BadSourceIp, packet.Cnonce0);
                                }
                                return(false);
                            }
                        }
                    }
                }


                var localTimeSec32 = TimeSec32UTC;
                var diffSec        = Math.Abs((int)unchecked (localTimeSec32 - receivedTimeSec32));
                if (diffSec > _config.StatelessPoW_MaxClockDifferenceS)
                {
                    // respond with error "try again with valid clock" - legitimate user has to get valid clock from some time server and synchronize itself with the server
                    if (_config.RespondErrors)
                    {
                        RespondToHello0(clientEndpoint, ServerHello0Status.ErrorBadStatelessProofOfWork_BadClock, packet.Cnonce0);
                    }
                    return(false);
                }

                var hash = _cryptoLibrary.GetHashSHA256(packet.OriginalPacketPayload);
                // calculate hash, considering entire packet data (including stateless PoW result)
                // verify hash result
                if (!StatelessPowHashIsOK(hash))
                {
                    HandleBadStatelessPowPacket(clientEndpoint);
                    // no response
                    return(false);
                }

                // check if hash is unique
                var dataIsUnique = _recentUniquePowData.TryInputData(hash, localTimeSec32);

                if (dataIsUnique)
                {
                    return(true);
                }
                else
                {
                    // respond with error "try again with unique PoW data"
                    if (_config.RespondErrors)
                    {
                        RespondToHello0(clientEndpoint, ServerHello0Status.ErrorTryAgainRightNowWithThisServer, packet.Cnonce0);
                    }
                    return(false);
                }

            default:
                throw new CcpBadPacketException();
            }
        }
Esempio n. 2
0
        /// <summary>
        /// sends responses
        /// executed by receiver thread
        /// </summary>
        bool PassPow1filter(IPEndPoint requesterEndpoint, RegisterPow1RequestPacket packet)
        {
            // verify size of Pow1 data
            if (packet.ProofOfWork1.Length != 64)
            {
                if (Configuration.VisionChannel?.GetAttentionTo(Configuration.VisionChannelSourceId, VisionChannelModuleName_reg_epSide) <= AttentionLevel.needsAttention)
                {
                    Configuration.VisionChannel?.Emit(Configuration.VisionChannelSourceId, VisionChannelModuleName_reg_epSide, AttentionLevel.needsAttention, $"pow1 filter rejected request from {requesterEndpoint}: invalid pow1 length");
                }
                return(false);
            }

            var localTimeSec32    = Timestamp32S;
            var timeDifferenceSec = Math.Abs((int)unchecked (localTimeSec32 - packet.Timestamp32S));

            if (timeDifferenceSec > Configuration.RegisterPow1_MaxTimeDifferenceS)
            {
                if (Configuration.VisionChannel?.GetAttentionTo(Configuration.VisionChannelSourceId, VisionChannelModuleName_reg_epSide) <= AttentionLevel.needsAttention)
                {
                    Configuration.VisionChannel?.Emit(Configuration.VisionChannelSourceId, VisionChannelModuleName_reg_epSide, AttentionLevel.needsAttention, $"pow1 filter rejected request from {requesterEndpoint}: invalid timestamp");
                }

                // respond with error "try again with valid clock" - legitimate user has to get valid clock from some time server and synchronize itself with the server
                if (Configuration.RespondToRegisterPow1Errors)
                {
                    RespondToRegisterPow1withError(requesterEndpoint, RegisterPow1ResponseStatusCode.rejected_badtimestamp, packet.Pow1RequestId);
                }
                return(false);
            }

            if (!Pow1IsOK(packet, requesterEndpoint.Address.GetAddressBytes()))
            {
                if (Configuration.VisionChannel?.GetAttentionTo(Configuration.VisionChannelSourceId, VisionChannelModuleName_reg_epSide) <= AttentionLevel.needsAttention)
                {
                    Configuration.VisionChannel?.Emit(Configuration.VisionChannelSourceId, VisionChannelModuleName_reg_epSide, AttentionLevel.needsAttention, $"pow1 filter rejected request from {requesterEndpoint}: invalid pow1");
                }

                OnReceivedBadRegisterReqPow1(requesterEndpoint);
                // no response
                return(false);
            }

            if (_recentUniquePow1Data != null)
            {
                // check if pow1 data is unique
                var dataIsUnique = _recentUniquePow1Data.TryInputData(packet.ProofOfWork1, localTimeSec32);
                if (dataIsUnique)
                {
                    return(true);
                }
                else
                {
                    if (Configuration.VisionChannel?.GetAttentionTo(Configuration.VisionChannelSourceId, VisionChannelModuleName_reg_epSide) <= AttentionLevel.needsAttention)
                    {
                        Configuration.VisionChannel?.Emit(Configuration.VisionChannelSourceId, VisionChannelModuleName_reg_epSide, AttentionLevel.needsAttention, $"pow1 filter rejected request from {requesterEndpoint}: pow1 data is not unique");
                    }

                    // respond with error "try again with unique PoW data"
                    if (Configuration.RespondToRegisterPow1Errors)
                    {
                        RespondToRegisterPow1withError(requesterEndpoint, RegisterPow1ResponseStatusCode.rejected_tryagainRightNowWithThisServer, packet.Pow1RequestId);
                    }
                    return(false);
                }
            }
            return(true);
        }