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(""); }
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); }
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); } }
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; } } } }
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()); }
private static string StoreToken(string token, string password) { BotToken.WriteToken(token, password); return(BotToken.GetTokenString()); }
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); }