コード例 #1
0
        public static string HandleTokenDecrypt()
        {
            if (BotToken.UsingPassword())
            {
                bool retry = true;
                while (retry)
                {
                    Console.Write("Enter your password: "******"Checksum mismatch. (New bot version or corrupted file)");
                        return(PromptAndStoreToken());
                    }
                    else if (!verified)
                    {
                        Console.Write("Could not decrypt token with that password. Try again? (y/n) ");
                        string yesno = Console.ReadLine();
                        retry = (yesno.Length > 0 && yesno.Substring(0, 1).ToLower() == "y");
                    }
                    else
                    {
                        Console.WriteLine("Token decrypted.");
                        return(BotToken.GetTokenString());
                    }
                }
                // User decided to stop retrying
                string pathToTokenFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "token").ToString();
                Console.WriteLine($"Store a new token by deleting the token file at {pathToTokenFile}");
            }
            else
            {
                bool verified = BotToken.DecryptAndVerify();
                if (!verified)
                {
                    Console.WriteLine("Checksum mismatch. (New bot version or corrupted file)");
                    return(PromptAndStoreToken());
                }
                else
                {
                    Console.WriteLine("Token decrypted.");
                    return(BotToken.GetTokenString());
                }
            }

            // Couldn't get a token
            return("");
        }
コード例 #2
0
        public static void WriteToken(string tokenStr, string password = "")
        {
            bool noPassword = (password == String.Empty);

            var crypto = _crypto ?? Crypto.Init();

            byte[] encrToken;

            if (noPassword)
            {
                encrToken = crypto.Encrypt(tokenStr);
            }
            else
            {
                encrToken = crypto.Encrypt(tokenStr, password);
            }

            if (File.Exists(_FILENAME))
            {
                File.Delete(_FILENAME);
            }

            byte flags = (byte)(noPassword ? 0x0 : BotTokenFlags.UsePassword);

            using (var fs = File.Create(_FILENAME)) {
                using (var writer = new BinaryWriter(fs)) {
                    // Header
                    writer.Write(_HEADER);

                    // Flags
                    writer.Write((byte)flags);

                    // Checksum
                    writer.Write(crypto.Checksum);

                    // Token
                    writer.Write(encrToken);
                }
            }

            _instance = new BotToken(_HEADER, flags, crypto.Checksum, Encoding.ASCII.GetBytes(tokenStr), BotTokenState.Valid);
        }
コード例 #3
0
        public static bool DecryptAndVerify(string password = "")
        {
            if (_instance == null)
            {
                throw new InvalidOperationException("BotToken not initialized");
            }
            else if (!(_instance._state == BotTokenState.Valid || _instance._state == BotTokenState.Unchecked))
            {
                throw new InvalidOperationException($"BotToken is not valid (state: {_instance._state.ToString()})");
            }

            Crypto crypto = _crypto ?? Crypto.Init();

            try {
                byte[] decrypted;
                if (password == String.Empty)
                {
                    decrypted = crypto.Decrypt(_instance._data);
                }
                else
                {
                    decrypted = crypto.Decrypt(_instance._data, password);
                }

                if (crypto.Checksum != _instance._checksum)
                {
                    _instance = _badToken;
                    return(false);
                }

                _instance._data  = decrypted;
                _instance._state = BotTokenState.Valid;

                return(true);
            }
            catch (CryptographicException) {
                // If the password is wrong or some corruption prevents even being able to decrypt,
                return(false);
            }
        }
コード例 #4
0
        public static void ReadToken()
        {
            if (!File.Exists(_FILENAME))
            {
                _instance = _missingToken;
                return;
            }

            using (var fs = File.OpenRead(_FILENAME)) {
                using (var reader = new BinaryReader(fs)) {
                    try {
                        byte[] fileHeader = reader.ReadBytes(_HEADER.Length);

                        if (!VerifyHeader(fileHeader))
                        {
                            _instance = _badToken;
                            return;
                        }

                        byte flags = reader.ReadByte();

                        uint checksum = reader.ReadUInt32();

                        long   dataSize = reader.BaseStream.Length - reader.BaseStream.Position;
                        byte[] data     = reader.ReadBytes(Convert.ToInt32(dataSize));

                        _instance = new BotToken(fileHeader, flags, checksum, data, BotTokenState.Unchecked);
                    }
                    catch (ArgumentException) {
                        // If we got here, we overran the EOF which means the file is considered corrupted
                        _instance = _badToken;
                    }
                    catch (OverflowException) {
                        // We can safely consider more then Int32.MaxInteger bytes of data to be corrupted
                        _instance = _badToken;
                    }
                }
            }
        }
コード例 #5
0
        private static string PromptAndStoreToken()
        {
            Console.Write("The Discord bot token needs to be stored. Enter the token: ");
            string token = Console.ReadLine();

            Console.WriteLine(
                Environment.NewLine +
                "The token will be stored encrypted. You may choose to a use a password to encrypt it. " +
                "If you don't use a password, a default encryption scheme will be used (this is less secure). " +
                Environment.NewLine
                );

            Console.Write("Use a password? (y/n) ");
            string yesno = Console.ReadLine();

            bool usePassword = (yesno.Length > 0 && yesno.Substring(0, 1).ToLower() == "y");

            string password = String.Empty;

            if (usePassword)
            {
                do
                {
                    Console.Write("Enter your password: "******"WARNING: If you forget your password you will have to delete the token file and re-encrypt the token.");
            }
            else
            {
                Console.WriteLine("Using default encryption.");
            }

            BotToken.WriteToken(token, password);
            return(BotToken.GetTokenString());
        }
コード例 #6
0
 private static string StoreToken(string token, string password)
 {
     BotToken.WriteToken(token, password);
     return(BotToken.GetTokenString());
 }
コード例 #7
0
        public async Task MainAsync(string[] cmdArgs)
        {
            // List of items to clean up when the bot exits
            _disposables = new List <IDisposable>();

            ArgParse args = new ArgParse();

            args.AddDefs(_ARG_DEFS);
            args.Parse(cmdArgs);

            bool   encryptOnlyMode = args.GetFlag("encrypt-only");
            string givenPassword   = args.GetValue("password");
            string givenToken      = args.GetValue("token");

            string token = String.Empty;

            if (encryptOnlyMode)
            {
                Console.WriteLine("Encrypt-only mode.");
                if (givenToken != String.Empty)
                {
                    if (givenPassword != String.Empty)
                    {
                        Console.WriteLine("Using password.");
                    }
                    else
                    {
                        Console.WriteLine("Not using password.");
                    }
                    StoreToken(givenToken, givenPassword);
                    Console.WriteLine("Token stored successfully.");
                }
                else
                {
                    Console.WriteLine("Encrypt-only mode must be used with a token. Run with option --token <string>.");
                }
                return;
            }
            else if (givenToken != String.Empty)
            {
                Console.WriteLine("Storing token.");
                if (givenPassword != String.Empty)
                {
                    Console.WriteLine("Using password.");
                }
                else
                {
                    Console.WriteLine("Not using password.");
                }
                StoreToken(givenToken, givenPassword);
                token = givenToken;
            }
            else
            {
                // Handle user-mode
                BotToken.ReadToken();
                switch (BotToken.GetTokenState())
                {
                case BotTokenState.Unchecked:
                case BotTokenState.Valid:
                    Console.WriteLine("Loading Discord bot token.");
                    token = HandleTokenDecrypt();
                    break;

                case BotTokenState.Missing:
                case BotTokenState.Outdated:
                case BotTokenState.Corrupted:
                    token = PromptAndStoreToken();
                    break;
                }
            }

            if (token == String.Empty)
            {
                Console.WriteLine("Stopping. (Press any key to end)");
                Console.ReadKey();
                return;
            }

            var config = new DiscordSocketConfig();

            config.AlwaysDownloadUsers = true;

            var client = new DiscordSocketClient(config);

            client.Log             += Log;
            client.Ready           += Ready;
            client.MessageReceived += MessageReceived;

            _adminList = new AdminList(client);
            _disposables.Add(_adminList);

            Server watsonLocal = new Server("localhost", 9000, false, DefaultRoute, false);

            watsonLocal.AddStaticRoute("get", "/hello/", HelloRoute);
            watsonLocal.AddStaticRoute("get", "/queue/", QueueRoute);

            _msgQueue = new Queue();

            await client.LoginAsync(TokenType.Bot, token);

            await client.StartAsync();

            await Task.Delay(-1);
        }