Exemple #1
0
        public void VerifyConfig(VerificationFlags verificationFlags = VerificationFlags.All)
        {
            List <string> errorMessages = new List <string>();

            if (DiscordLink.Obj.DiscordClient == null)
            {
                errorMessages.Add("[General Verification] No Discord client connected.");
            }

            if (verificationFlags.HasFlag(VerificationFlags.Static))
            {
                // Bot Token
                if (string.IsNullOrWhiteSpace(Data.BotToken))
                {
                    errorMessages.Add("[Bot Token] Bot token not configured. See Github page for install instructions.");
                }

                // Player configs
                foreach (DiscordPlayerConfig playerConfig in Data.PlayerConfigs)
                {
                    if (string.IsNullOrWhiteSpace(playerConfig.Username))
                    {
                        continue;
                    }

                    bool found = false;
                    foreach (User user in UserManager.Users)
                    {
                        if (user.Name == playerConfig.Username)
                        {
                            found = true;
                            break;
                        }
                    }
                    if (!found)
                    {
                        errorMessages.Add("[Player Configs] No user with name \"" + playerConfig.Username + "\" was found");
                    }
                }

                // Eco command channel
                if (!string.IsNullOrWhiteSpace(Data.EcoCommandChannel) && Data.EcoCommandChannel.Contains("#"))
                {
                    errorMessages.Add("[Eco Command Channel] Channel name contains a channel indicator (#). The channel indicator will be added automatically and adding one manually may cause message sending to fail");
                }

                if (!string.IsNullOrWhiteSpace(Data.InviteMessage) && !Data.InviteMessage.Contains(InviteCommandLinkToken))
                {
                    errorMessages.Add("[Invite Message] Message does not contain the invite link token " + InviteCommandLinkToken + ". If the invite link has been added manually, consider adding it to the network config instead");
                }

                // Report errors
                if (errorMessages.Count <= 0)
                {
                    Logger.Info("Static configuration verification completed without errors");
                }
                else
                {
                    string concatenatedMessages = "";
                    foreach (string message in errorMessages)
                    {
                        concatenatedMessages += message + "\n";
                    }
                    Logger.Error("Static configuration errors detected!\n" + concatenatedMessages.Trim());
                }
            }

            // Discord guild and channel information isn't available the first time this function is called
            if (verificationFlags.HasFlag(VerificationFlags.ChannelLinks) && DiscordLink.Obj.DiscordClient != null && ChannelLinks.Count > 0)
            {
                foreach (ChannelLink link in _channelLinks)
                {
                    if (link.Verify())
                    {
                        string linkID = link.ToString();
                        if (!_verifiedLinks.Contains(linkID))
                        {
                            _verifiedLinks.Add(linkID);
                            Logger.Info("Channel Link Verified: " + linkID);
                        }
                    }
                }

                if (_verifiedLinks.Count >= _channelLinks.Count)
                {
                    Logger.Info("All channel links sucessfully verified");
                }
                else if (_linkVerificationTimeoutTimer == null) // If no timer is used, then the discord guild info should already be set up
                {
                    ReportUnverifiedChannels();
                }
            }
        }
        public unsafe int ValidateCertificate(QUIC_BUFFER *certificatePtr, QUIC_BUFFER *chainPtr, out X509Certificate2?certificate)
        {
            SslPolicyErrors sslPolicyErrors   = SslPolicyErrors.None;
            IntPtr          certificateBuffer = 0;
            int             certificateLength = 0;

            X509Chain?       chain  = null;
            X509Certificate2?result = null;

            try
            {
                if (certificatePtr is not null)
                {
                    chain = new X509Chain();
                    if (_certificateChainPolicy != null)
                    {
                        chain.ChainPolicy = _certificateChainPolicy;
                    }
                    else
                    {
                        chain.ChainPolicy.RevocationMode = _revocationMode;
                        chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;

                        // TODO: configure chain.ChainPolicy.CustomTrustStore to mirror behavior of SslStream.VerifyRemoteCertificate (https://github.com/dotnet/runtime/issues/73053)
                    }

                    // set ApplicationPolicy unless already provided.
                    if (chain.ChainPolicy.ApplicationPolicy.Count == 0)
                    {
                        // Authenticate the remote party: (e.g. when operating in server mode, authenticate the client).
                        chain.ChainPolicy.ApplicationPolicy.Add(_isClient ? s_serverAuthOid : s_clientAuthOid);
                    }

                    if (MsQuicApi.UsesSChannelBackend)
                    {
                        result = new X509Certificate2((IntPtr)certificatePtr);
                    }
                    else
                    {
                        if (certificatePtr->Length > 0)
                        {
                            certificateBuffer = (IntPtr)certificatePtr->Buffer;
                            certificateLength = (int)certificatePtr->Length;
                            result            = new X509Certificate2(certificatePtr->Span);
                        }

                        if (chainPtr->Length > 0)
                        {
                            X509Certificate2Collection additionalCertificates = new X509Certificate2Collection();
                            additionalCertificates.Import(chainPtr->Span);
                            chain.ChainPolicy.ExtraStore.AddRange(additionalCertificates);
                        }
                    }
                }

                if (result is not null)
                {
                    bool checkCertName = !chain !.ChainPolicy !.VerificationFlags.HasFlag(X509VerificationFlags.IgnoreInvalidName);
                    sslPolicyErrors |= CertificateValidation.BuildChainAndVerifyProperties(chain !, result, checkCertName, !_isClient, _targetHost, certificateBuffer, certificateLength);
                }
                else if (_certificateRequired)
                {
                    sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNotAvailable;
                }

                int status = QUIC_STATUS_SUCCESS;
                if (_validationCallback is not null)
                {
                    if (!_validationCallback(_connection, result, chain, sslPolicyErrors))
                    {
                        if (_isClient)
                        {
                            throw new AuthenticationException(SR.net_quic_cert_custom_validation);
                        }

                        status = QUIC_STATUS_USER_CANCELED;
                    }
                }
                else if (sslPolicyErrors != SslPolicyErrors.None)
                {
                    if (_isClient)
                    {
                        throw new AuthenticationException(SR.Format(SR.net_quic_cert_chain_validation, sslPolicyErrors));
                    }

                    status = QUIC_STATUS_HANDSHAKE_FAILURE;
                }

                certificate = result;
                return(status);
            }
            catch
            {
                result?.Dispose();
                throw;
            }
            finally
            {
                if (chain is not null)
                {
                    X509ChainElementCollection elements = chain.ChainElements;
                    for (int i = 0; i < elements.Count; i++)
                    {
                        elements[i].Certificate.Dispose();
                    }

                    chain.Dispose();
                }
            }
        }