Exemplo n.º 1
0
        public async Task EncryptedFileConfig()
        {
            // Restart the service specifying the configuration via
            // an encrypted physical configuration file.

            var password = "******";
            var vault    = new NeonVault(passwordName => password);

            using (var tempFolder = new TempFolder())
            {
                var decryptedPath = Path.Combine(tempFolder.Path, "decrypted");
                var encryptedPath = Path.Combine(tempFolder.Path, "encrypted");

                File.WriteAllText(decryptedPath, "From: ENCRYPTED FILE");
                vault.Encrypt(decryptedPath, encryptedPath, "foo");
                Assert.True(NeonVault.IsEncrypted(encryptedPath));

                var service = CreateService();

                service.SetConfigFilePath("/etc/web/response", encryptedPath, passwordName => password);

                fixture.Restart(() => service);
                Assert.True(fixture.IsRunning);

                var client = fixture.GetHttpClient();

                Assert.Equal("From: ENCRYPTED FILE", await client.GetStringAsync("/"));
            }
        }
Exemplo n.º 2
0
        /// <inheritdoc/>
        public override void Run(CommandLine commandLine)
        {
            if (commandLine.HasHelpOption)
            {
                Console.WriteLine(usage);
                Program.Exit(0);
            }

            var path = commandLine.Arguments.ElementAtOrDefault(0);

            if (string.IsNullOrEmpty(path))
            {
                Console.Error.WriteLine("*** ERROR: The PATH argument is required.");
                Program.Exit(1);
            }

            if (NeonVault.IsEncrypted(path, out var passwordName))
            {
                Console.Write(passwordName);

                if (!commandLine.HasOption("-n"))
                {
                    Console.WriteLine();
                }
            }
            else
            {
                Program.Exit(1);
            }

            Program.Exit(0);
        }
Exemplo n.º 3
0
        public async Task EncryptedEnvironmentFileConfig()
        {
            // Restart the service specifying by loading an encrypted file with
            // the environment variable assignment.

            var password = "******";
            var vault    = new NeonVault(passwordName => password);

            using (var tempFolder = new TempFolder())
            {
                var decryptedPath = Path.Combine(tempFolder.Path, "decrypted");
                var encryptedPath = Path.Combine(tempFolder.Path, "encrypted");

                File.WriteAllText(decryptedPath,
                                  @"# This is a comment.

WEB_RESULT=HELLO WORLD! (encrypted)
");

                var service = CreateService();

                service.LoadEnvironmentVariableFile(decryptedPath);
                vault.Encrypt(decryptedPath, encryptedPath, "foo");
                Assert.True(NeonVault.IsEncrypted(encryptedPath));

                fixture.Restart(() => service);
                Assert.True(fixture.IsRunning);

                var client = fixture.GetHttpClient();

                Assert.Equal("HELLO WORLD! (encrypted)", await client.GetStringAsync("/"));
            }
        }
Exemplo n.º 4
0
        /// <inheritdoc/>
        public override void Run(CommandLine commandLine)
        {
            if (commandLine.HasHelpOption)
            {
                Console.WriteLine(usage);
                Program.Exit(0);
            }

            var sourcePath = commandLine.Arguments.ElementAtOrDefault(0);
            var targetPath = commandLine.Arguments.ElementAtOrDefault(1);

            if (string.IsNullOrEmpty(sourcePath))
            {
                Console.Error.WriteLine("*** ERROR: The SOURCE argument is required.");
                Program.Exit(1);
            }

            if (string.IsNullOrEmpty(targetPath))
            {
                Console.Error.WriteLine("*** ERROR: The TARGET argument is required.");
                Program.Exit(1);
            }

            if (!NeonVault.IsEncrypted(sourcePath))
            {
                Console.Error.WriteLine($"*** ERROR: The [{sourcePath}] file is not encrypted.");
                Program.Exit(1);
            }

            var vault = new NeonVault(Program.LookupPassword);

            vault.Decrypt(sourcePath, targetPath);

            Program.Exit(0);
        }
Exemplo n.º 5
0
        public async Task VariableInjectEncrypted()
        {
            var orgDirectory = Environment.CurrentDirectory;

            try
            {
                using (var testManager = new KubeTestManager())
                {
                    using (var runner = new ProgramRunner())
                    {
                        using (var tempFolder = new TempFolder())
                        {
                            Environment.CurrentDirectory = tempFolder.Path;

                            var vault = new NeonVault(Program.LookupPassword);

                            // Create a test password and a [.password-name] file in the
                            // temp test folder.

                            var result = await runner.ExecuteAsync(Program.Main, "tool", "password", "set", "test");

                            Assert.Equal(0, result.ExitCode);

                            //-------------------------------------------------
                            // Verify that we can inject variables into an
                            // ENCRYPTED file.

                            File.WriteAllText("test.cmd", "type %1 > output.txt");

                            File.WriteAllText("file.txt",
                                              @"
$<<TEST_A>>
$<<TEST_B>>
$<<TEST_C>>
$<<TEST_D>>
");
                            File.WriteAllBytes("file.txt", vault.Encrypt("file.txt", "test"));
                            Assert.True(NeonVault.IsEncrypted("file.txt"));

                            result = await runner.ExecuteAsync(Program.Main, "tool", "run", "--TEST_A=A-VALUE", "--TEST_B=B-VALUE", "--TEST_C=C-VALUE", "--TEST_D=D-VALUE", "--", "test.cmd", "_..file.txt");

                            Assert.Equal(0, result.ExitCode);

                            var output = File.ReadAllText("output.txt");

                            Assert.Contains("A-VALUE", output);
                            Assert.Contains("B-VALUE", output);
                            Assert.Contains("C-VALUE", output);
                            Assert.Contains("D-VALUE", output);
                            File.Delete("output.txt");
                            File.Delete("file.txt");
                        }
                    }
                }
            }
            finally
            {
                Environment.CurrentDirectory = orgDirectory;
            }
        }
Exemplo n.º 6
0
        public void LoadEnvironmentEncrypted()
        {
            // Verify that we can load an encryoted settings file into the
            // environment variables.

            using (var testManager = new KubeTestManager())
            {
                try
                {
                    using (var tempFile = new TempFile())
                    {
                        // Initialze the file.

                        using (var writer = new StreamWriter(tempFile.Path))
                        {
                            foreach (var item in testSettings)
                            {
                                writer.WriteLine($"{item.Key}={item.Value}");
                            }
                        }

                        var passwordPath = Path.Combine(KubeHelper.PasswordsFolder, "test");

                        File.WriteAllText(passwordPath, password);

                        var vault = new NeonVault(KubeHelper.LookupPassword);

                        File.WriteAllBytes(tempFile.Path, vault.Encrypt(tempFile.Path, "test"));
                        Assert.True(NeonVault.IsEncrypted(tempFile.Path));

                        // Perform the test.

                        Assert.Null(TestContext.Current);

                        using (var testContext = new TestContext())
                        {
                            Assert.Same(testContext, TestContext.Current);

                            testContext.LoadEnvironment(tempFile.Path, KubeHelper.LookupPassword);

                            foreach (var item in testSettings)
                            {
                                Assert.Equal(item.Value, Environment.GetEnvironmentVariable(item.Key));
                            }
                        }
                    }
                }
                finally
                {
                    // Be sure to remove the test enmvironment variables.

                    foreach (var item in testSettings)
                    {
                        Environment.SetEnvironmentVariable(item.Key, null);
                    }
                }
            }
        }
Exemplo n.º 7
0
 /// <summary>
 /// Examines the file at <paramref name="path"/>, decrypting it to a temporary file
 /// if necessary.  The method will then call <paramref name="action"/> passing the
 /// path to the original file (if it wasn't encrypted or to the decrypted file.
 /// </summary>
 /// <param name="path">The file path.</param>
 /// <param name="action">Called with the path to a decrypted file.</param>
 private void DecryptWithAction(string path, Action <string> action)
 {
     if (!NeonVault.IsEncrypted(path))
     {
         action(path);
     }
     else
     {
         using (var tempFile = new TempFile())
         {
             vault.Decrypt(path, tempFile.Path);
             action(tempFile.Path);
         }
     }
 }
Exemplo n.º 8
0
        public void LoadSettingsEncrypted()
        {
            // Verify that we can load an encrypted settings file into the
            // [TestContext.Settings] dictionary.

            using (var testManager = new KubeTestManager())
            {
                using (var tempFile = new TempFile())
                {
                    // Initialze the file.

                    using (var writer = new StreamWriter(tempFile.Path))
                    {
                        foreach (var item in testSettings)
                        {
                            writer.WriteLine($"{item.Key}={item.Value}");
                        }
                    }

                    var passwordPath = Path.Combine(KubeHelper.PasswordsFolder, "test");

                    File.WriteAllText(passwordPath, password);

                    var vault = new NeonVault(KubeHelper.LookupPassword);

                    File.WriteAllBytes(tempFile.Path, vault.Encrypt(tempFile.Path, "test"));
                    Assert.True(NeonVault.IsEncrypted(tempFile.Path));

                    // Perform the test.

                    Assert.Null(TestContext.Current);

                    using (var testContext = new TestContext())
                    {
                        Assert.Same(testContext, TestContext.Current);

                        testContext.LoadSettings(tempFile.Path, KubeHelper.LookupPassword);

                        foreach (var item in testSettings)
                        {
                            Assert.Equal(item.Value, testContext.Settings[item.Key]);
                        }
                    }
                }
            }
        }
Exemplo n.º 9
0
        public void Unencrypted()
        {
            // Verify that "decrypting" an unencrypted file simply copies
            // the data to the output.

            var vault = new NeonVault(GetPassword);

            using (var tempFolder = new TempFolder())
            {
                var sourcePath = Path.Combine(tempFolder.Path, "source.txt");
                var targetPath = Path.Combine(tempFolder.Path, "target.txt");

                File.WriteAllText(sourcePath, unencryptedText);

                vault.Decrypt(sourcePath, targetPath);

                Assert.Equal(unencryptedText, File.ReadAllText(targetPath));
                Assert.False(NeonVault.IsEncrypted(sourcePath));
                Assert.False(NeonVault.IsEncrypted(targetPath));
            }
        }
Exemplo n.º 10
0
        /// <inheritdoc/>
        public override async Task RunAsync(CommandLine commandLine)
        {
            if (commandLine.HasHelpOption)
            {
                Console.WriteLine(usage);
                Program.Exit(0);
            }

            var path = commandLine.Arguments.ElementAtOrDefault(0);

            if (string.IsNullOrEmpty(path))
            {
                Console.Error.WriteLine("*** ERROR: The PATH argument is required.");
                Program.Exit(1);
            }

            if (!NeonVault.IsEncrypted(path, out var passwordName))
            {
                Console.Error.WriteLine($"*** ERROR: The [{path}] file is not encrypted.");
                Program.Exit(1);
            }

            var vault    = new NeonVault(Program.LookupPassword);
            var fileName = Path.GetFileName(path);

            using (var tempFolder = new TempFolder())
            {
                var tempPath = Path.Combine(tempFolder.Path, fileName);

                // Decrypt the file to a secure temporary folder, launch the
                // editor and re-encrypt the file after the editor returns.

                vault.Decrypt(path, tempPath);
                NeonHelper.OpenEditor(tempPath);
                vault.Encrypt(tempPath, path, passwordName);
            }

            Program.Exit(0);
            await Task.CompletedTask;
        }
Exemplo n.º 11
0
        public void FileToFile()
        {
            var vault = new NeonVault(GetPassword);

            using (var tempFolder = new TempFolder())
            {
                var sourcePath = Path.Combine(tempFolder.Path, "source.txt");
                var targetPath = Path.Combine(tempFolder.Path, "target.txt");

                File.WriteAllText(sourcePath, unencryptedText);

                vault.Encrypt(sourcePath, targetPath, "password-1");

                using (var target = new FileStream(targetPath, FileMode.Open, FileAccess.Read))
                {
                    var decrypted = vault.Decrypt(target);

                    Assert.Equal(unencryptedBytes, decrypted);
                }

                Assert.False(NeonVault.IsEncrypted(sourcePath));
                Assert.True(NeonVault.IsEncrypted(targetPath));
            }
        }
Exemplo n.º 12
0
        public void VaultDecrypt()
        {
            using (var manager = new KubeTestManager())
            {
                using (var tempFolder = new TempFolder())
                {
                    var orgDir = Environment.CurrentDirectory;

                    Environment.CurrentDirectory = tempFolder.Path;
                    NeonHelper.OpenEditorHandler = path => File.WriteAllText(path, plainText);

                    try
                    {
                        using (var passwordFile = new TempFile(folder: KubeHelper.PasswordsFolder))
                        {
                            File.WriteAllText(passwordFile.Path, testPassword);

                            var vault = new NeonVault(passwordName => testPassword);

                            using (var runner = new ProgramRunner())
                            {
                                // Verify that the SOURCE argument is required.

                                var result = runner.Execute(Program.Main, "vault", "decrypt");

                                Assert.NotEqual(0, result.ExitCode);
                                Assert.Contains("*** ERROR: The SOURCE argument is required.", result.ErrorText);

                                // Verify that the TARGET argument is required.

                                result = runner.Execute(Program.Main, "vault", "decrypt");

                                Assert.NotEqual(0, result.ExitCode);
                                Assert.Contains("*** ERROR: The SOURCE argument is required.", result.ErrorText);

                                // Verify that the SOURCE-PATH argument is required.

                                result = runner.Execute(Program.Main, "vault", "decrypt", "test.txt");

                                Assert.NotEqual(0, result.ExitCode);
                                Assert.Contains("*** ERROR: The TARGET argument is required.", result.ErrorText);

                                // Verify that we can create an encrypted file with an explicitly
                                // named password.

                                result = runner.Execute(Program.Main, "vault", "create", "test1.txt", passwordFile.Name);

                                Assert.Equal(0, result.ExitCode);
                                Assert.True(NeonVault.IsEncrypted("test1.txt", out var passwordName));
                                Assert.Equal(passwordFile.Name, passwordName);
                                Assert.Equal(plainText, Encoding.UTF8.GetString(vault.Decrypt("test1.txt")));

                                // Verify that we can decrypt the file.

                                result = runner.Execute(Program.Main, "vault", "decrypt", "test1.txt", "decrypted.txt");

                                Assert.Equal(0, result.ExitCode);
                                Assert.True(NeonVault.IsEncrypted("test1.txt", out passwordName));
                                Assert.True(!NeonVault.IsEncrypted("decrypted.txt", out passwordName));
                                Assert.Equal(plainText, File.ReadAllText("decrypted.txt"));
                            }
                        }
                    }
                    finally
                    {
                        Environment.CurrentDirectory = orgDir;
                        NeonHelper.OpenEditorHandler = null;
                    }
                }
            }
        }
Exemplo n.º 13
0
        /// <inheritdoc/>
        public override async Task RunAsync(CommandLine commandLine)
        {
            if (commandLine.HasHelpOption)
            {
                Console.WriteLine(usage);
                Program.Exit(0);
            }

            var splitCommandLine = commandLine.Split("--");
            var leftCommandLine  = splitCommandLine.Left;
            var rightCommandLine = splitCommandLine.Right;

            if (rightCommandLine == null || rightCommandLine.Arguments.Length == 0)
            {
                Console.Error.WriteLine("*** ERROR: Expected a command after a [--] argument.");
                Program.Exit(1);
            }

            // All arguments on the left command line should be VARIABLES files.
            // We're going to open each of these and set any enviroment variables
            // like [NAME=VALUE] we find.
            //
            // Note that these files may be encrypted.  If any are, we'll decrypt
            // to a temporary file before we read them.

            foreach (var path in leftCommandLine.Arguments)
            {
                if (!File.Exists(path))
                {
                    Console.Error.WriteLine($"*** ERROR: File [{path}] does not exist.");
                    Program.Exit(1);
                }

                DecryptWithAction(path,
                                  decryptedPath =>
                {
                    var lineNumber = 1;

                    foreach (var line in File.ReadAllLines(decryptedPath))
                    {
                        var trimmed = line.Trim();

                        if (line == string.Empty || line.StartsWith("#"))
                        {
                            continue;
                        }

                        var fields = line.Split('=', 2);

                        if (fields.Length != 2 || fields[0] == string.Empty)
                        {
                            Console.Error.WriteLine($"*** ERROR: [{path}:{lineNumber}] is not formatted like: NAME=VALUE");
                            Program.Exit(1);
                        }

                        var name  = fields[0].Trim();
                        var value = fields[1].Trim();

                        Environment.SetEnvironmentVariable(name, value);

                        lineNumber++;
                    }
                });
            }

            // Any left command line options with a "--" prefix also specify environment variables.

            foreach (var option in leftCommandLine.Options.Where(o => o.Key.StartsWith("--")))
            {
                Environment.SetEnvironmentVariable(option.Key.Substring(2), option.Value);
            }

            // We've read all of the variable files and left command line options
            // and initialized all environment variables.  Now we need to process
            // and then execute the right command line.

            var tempFiles = new List <TempFile>();

            try
            {
                var subcommand = rightCommandLine.Items;

                // Note that the first element of the subcommand specifies the
                // executable so we don't need to process that.

                for (int i = 1; i < subcommand.Length; i++)
                {
                    var arg = subcommand[i];

                    if (arg.StartsWith("_..."))
                    {
                        // Argument is a reference to a potentially encrypted
                        // file that needs to be passed decrypted.

                        var path = arg.Substring(4);

                        if (!File.Exists(path))
                        {
                            Console.Error.WriteLine($"*** ERROR: File [{path}] does not exist.");
                            Program.Exit(1);
                        }

                        if (NeonVault.IsEncrypted(path))
                        {
                            var tempFile = new TempFile();

                            tempFiles.Add(tempFile);
                            vault.Decrypt(path, tempFile.Path);

                            path = tempFile.Path;
                        }

                        subcommand[i] = path;
                    }
                    else if (arg.StartsWith("_.."))
                    {
                        // Argument is a reference to a potentially encrypted text file
                        // with environment variable references we'll need to update.

                        var path = arg.Substring(3);

                        if (!File.Exists(path))
                        {
                            Console.Error.WriteLine($"*** ERROR: File [{path}] does not exist.");
                            Program.Exit(1);
                        }

                        if (NeonVault.IsEncrypted(path))
                        {
                            var tempFile = new TempFile();

                            tempFiles.Add(tempFile);
                            vault.Decrypt(path, tempFile.Path);

                            path = tempFile.Path;
                        }

                        subcommand[i] = path;

                        // Perform the subsitutions.

                        var unprocessed      = File.ReadAllText(path);
                        var processed        = string.Empty;
                        var linuxLineEndings = !unprocessed.Contains("\r\n");

                        using (var reader = new StreamReader(path))
                        {
                            using (var preprocessor = new PreprocessReader(reader))
                            {
                                preprocessor.ExpandVariables        = true;
                                preprocessor.LineEnding             = linuxLineEndings ? LineEnding.LF : LineEnding.CRLF;
                                preprocessor.ProcessStatements      = false;
                                preprocessor.StripComments          = false;
                                preprocessor.VariableExpansionRegex = PreprocessReader.AngleVariableExpansionRegex;

                                processed = preprocessor.ReadToEnd();
                            }
                        }

                        File.WriteAllText(path, processed);
                    }
                    else if (arg.StartsWith("_."))
                    {
                        // Argument is a reference to an environment variable.

                        var name = arg.Substring(2);

                        if (name == string.Empty)
                        {
                            Console.Error.WriteLine($"*** ERROR: Subcommand argument [{arg}] is not valid.");
                            Program.Exit(1);
                        }

                        var value = Environment.GetEnvironmentVariable(name);

                        if (value == null)
                        {
                            Console.Error.WriteLine($"*** ERROR: Subcommand argument [{arg}] references an undefined environment variable.");
                            Program.Exit(2);
                        }

                        subcommand[i] = value;
                    }
                    else if (arg.StartsWith("-"))
                    {
                        // Argument is a command line option.  We'll check to see if
                        // it contains a reference to an environment variable.

                        var valuePos = arg.IndexOf("=_.");

                        if (valuePos != -1)
                        {
                            var optionPart = arg.Substring(0, valuePos);
                            var name       = arg.Substring(valuePos + 3);

                            if (name == string.Empty)
                            {
                                Console.Error.WriteLine($"*** ERROR: Subcommand argument [{arg}] is not valid.");
                                Program.Exit(1);
                            }

                            var value = Environment.GetEnvironmentVariable(name);

                            if (value == null)
                            {
                                Console.Error.WriteLine($"*** ERROR: Subcommand argument [{arg}] references an undefined environment variable.");
                                Program.Exit(1);
                            }

                            subcommand[i] = $"{optionPart}={value}";
                        }
                    }
                    else
                    {
                        // Otherwise, expand any envrionment variable references.

                        subcommand[i] = Environment.ExpandEnvironmentVariables(subcommand[i]);
                    }
                }

                // Execute the subcommand.

                var subcommandArgs = new List <object>();

                foreach (var subcommandArg in subcommand)
                {
                    subcommandArgs.Add(subcommandArg);
                }

                var exitCode = NeonHelper.Execute(subcommand[0], subcommandArgs.Skip(1).ToArray());

                Program.Exit(exitCode);
            }
            finally
            {
                foreach (var tempFile in tempFiles)
                {
                    tempFile.Dispose();
                }
            }

            Program.Exit(0);
            await Task.CompletedTask;
        }
Exemplo n.º 14
0
        /// <inheritdoc/>
        public override void Run(CommandLine commandLine)
        {
            if (commandLine.HasHelpOption)
            {
                Console.WriteLine(usage);
                Program.Exit(0);
            }

            var sourcePath   = commandLine.Arguments.ElementAtOrDefault(0);
            var targetPath   = commandLine.Arguments.ElementAtOrDefault(1);
            var passwordName = commandLine.Arguments.ElementAtOrDefault(2);
            var inPlace      = false;

            if (string.IsNullOrEmpty(sourcePath))
            {
                Console.Error.WriteLine("*** ERROR: The PATH argument is required.");
                Program.Exit(1);
            }

            if (string.IsNullOrEmpty(targetPath))
            {
                targetPath = sourcePath;
                inPlace    = true;
            }

            if (string.IsNullOrEmpty(targetPath) || string.IsNullOrEmpty(passwordName))
            {
                passwordName = commandLine.GetOption("--password-name");

                if (passwordName != null && string.IsNullOrWhiteSpace(passwordName))
                {
                    Console.Error.WriteLine("*** ERROR: [--password-name] specifies a blank password.");
                    Program.Exit(1);
                }

                if (passwordName == null)
                {
                    passwordName = commandLine.GetOption("-p");

                    if (passwordName != null && string.IsNullOrWhiteSpace(passwordName))
                    {
                        Console.Error.WriteLine("*** ERROR: [-p] specifies a blank password.");
                        Program.Exit(1);
                    }
                }
            }

            if (NeonVault.IsEncrypted(sourcePath))
            {
                Console.Error.WriteLine($"*** ERROR: The [{sourcePath}] file is already encrypted.");
                Program.Exit(1);
            }

            if (string.IsNullOrEmpty(passwordName))
            {
                passwordName = Program.GetDefaultPasswordName(targetPath);
            }

            if (string.IsNullOrEmpty(passwordName))
            {
                Console.Error.WriteLine("*** ERROR: A PASSWORD-NAME argument or [.password-name] file is required.");
                Program.Exit(1);
            }

            var vault = new NeonVault(Program.LookupPassword);

            if (inPlace)
            {
                // For in-place encryption, we'll first copy the file to
                // a secure folder and then encrypt from there to overwrite
                // the original file.

                using (var tempFile = new TempFile())
                {
                    File.Copy(sourcePath, tempFile.Path);
                    vault.Encrypt(tempFile.Path, sourcePath, passwordName);
                }
            }
            else
            {
                // Otherwise, we can simply encrypt from the source to the target.

                vault.Encrypt(sourcePath, targetPath, passwordName);
            }

            Program.Exit(0);
        }
Exemplo n.º 15
0
        public async Task VaultEncrypt()
        {
            using (var testManager = new KubeTestManager())
            {
                using (var tempFolder = new TempFolder())
                {
                    var orgDir = Environment.CurrentDirectory;

                    Environment.CurrentDirectory = tempFolder.Path;
                    NeonHelper.OpenEditorHandler = path => File.WriteAllText(path, plainText);

                    try
                    {
                        using (var passwordFile = new TempFile(folder: KubeHelper.PasswordsFolder))
                        {
                            File.WriteAllText(passwordFile.Path, testPassword);

                            var vault = new NeonVault(passwordName => testPassword);

                            using (var runner = new ProgramRunner())
                            {
                                // Verify that the PATH argument is required.

                                var result = await runner.ExecuteAsync(Program.Main, "tool", "vault", "encrypt");

                                Assert.NotEqual(0, result.ExitCode);
                                Assert.Contains("*** ERROR: The PATH argument is required.", result.ErrorText);

                                // Verify that the TARGET argument is required when [--password-name]
                                // or [--p] is not present.

                                result = await runner.ExecuteAsync(Program.Main, "tool", "vault", "decrypt", "source.txt");

                                Assert.NotEqual(0, result.ExitCode);
                                Assert.Contains("*** ERROR: The TARGET argument is required.", result.ErrorText);

                                // Verify that we can encrypt a file in-place, specifying an
                                // explicit password name (using --password-name=NAME).

                                File.WriteAllText("test1.txt", plainText);

                                result = await runner.ExecuteAsync(Program.Main, "tool", "vault", "encrypt", "test1.txt", $"--password-name={passwordFile.Name}");

                                Assert.Equal(0, result.ExitCode);
                                Assert.True(NeonVault.IsEncrypted("test1.txt", out var passwordName));
                                Assert.Equal(passwordFile.Name, passwordName);
                                Assert.Equal(plainText, Encoding.UTF8.GetString(vault.Decrypt("test1.txt")));

                                // Verify that we can encrypt a file in-place, specifying an
                                // explicit password name (using --p=NAME).

                                File.WriteAllText("test2.txt", plainText);

                                result = await runner.ExecuteAsync(Program.Main, "tool", "vault", "encrypt", "test2.txt", $"-p={passwordFile.Name}");

                                Assert.Equal(0, result.ExitCode);
                                Assert.True(NeonVault.IsEncrypted("test2.txt", out passwordName));
                                Assert.Equal(passwordFile.Name, passwordName);
                                Assert.Equal(plainText, Encoding.UTF8.GetString(vault.Decrypt("test2.txt")));

                                // Verify that we get an error trying to encrypt in-place without a
                                // password name being explicitly specified and also without a
                                // [.password-name] file present.

                                File.WriteAllText("test3.txt", plainText);

                                result = await runner.ExecuteAsync(Program.Main, "tool", "vault", "encrypt", "test3.txt");

                                Assert.NotEqual(0, result.ExitCode);
                                Assert.Contains("*** ERROR: A PASSWORD-NAME argument or [.password-name] file is required.", result.ErrorText);

                                // Verify that we get an error trying to encrypt (not in-place) without a
                                // password name being explicitly specified and also without a
                                // [.password-name] file present.

                                File.WriteAllText("test4.txt", plainText);

                                result = await runner.ExecuteAsync(Program.Main, "tool", "vault", "encrypt", "test4.txt", "test4.encypted.txt");

                                Assert.NotEqual(0, result.ExitCode);
                                Assert.Contains("*** ERROR: A PASSWORD-NAME argument or [.password-name] file is required.", result.ErrorText);

                                // Verify that we can encrypt a file to another with
                                // and explicit password argument.

                                File.WriteAllText("test5.txt", plainText);

                                result = await runner.ExecuteAsync(Program.Main, "tool", "vault", "encrypt", "test5.txt", "test5.encypted.txt", passwordName);

                                Assert.Equal(0, result.ExitCode);
                                Assert.True(NeonVault.IsEncrypted("test5.encypted.txt", out passwordName));
                                Assert.Equal(passwordFile.Name, passwordName);
                                Assert.Equal(plainText, Encoding.UTF8.GetString(vault.Decrypt("test5.encypted.txt")));

                                // Verify that we can encrypt a file to another with
                                // and explicit [--password-name] option.

                                File.WriteAllText("test6.txt", plainText);

                                result = await runner.ExecuteAsync(Program.Main, "tool", "vault", "encrypt", "test6.txt", "test6.encypted.txt", $"--password-name={passwordName}");

                                Assert.Equal(0, result.ExitCode);
                                Assert.True(NeonVault.IsEncrypted("test6.encypted.txt", out passwordName));
                                Assert.Equal(passwordFile.Name, passwordName);
                                Assert.Equal(plainText, Encoding.UTF8.GetString(vault.Decrypt("test6.encypted.txt")));

                                // Verify that we can encrypt a file in-place using a [.password-name] file.

                                File.WriteAllText("test7.txt", plainText);
                                File.WriteAllText(".password-name", passwordName);

                                result = await runner.ExecuteAsync(Program.Main, "tool", "vault", "encrypt", "test7.txt");

                                Assert.Equal(0, result.ExitCode);
                                Assert.True(NeonVault.IsEncrypted("test7.txt", out passwordName));
                                Assert.Equal(passwordFile.Name, passwordName);
                                Assert.Equal(plainText, Encoding.UTF8.GetString(vault.Decrypt("test7.txt")));

                                // Verify that we can encrypt a file (not in-place) to another where
                                // the source file is located in a different directory from the target
                                // to ensure that we look for the [.password-name] file starting at
                                // the target directory.

                                using (var tempFile = new TempFile())
                                {
                                    File.WriteAllText(tempFile.Path, plainText);

                                    result = await runner.ExecuteAsync(Program.Main, "tool", "vault", "encrypt", tempFile.Path, "test8.encrypted.txt");

                                    Assert.Equal(0, result.ExitCode);
                                    Assert.True(NeonVault.IsEncrypted("test8.encrypted.txt", out passwordName));
                                    Assert.Equal(passwordFile.Name, passwordName);
                                    Assert.Equal(plainText, Encoding.UTF8.GetString(vault.Decrypt("test8.encrypted.txt")));
                                }
                            }
                        }
                    }
                    finally
                    {
                        Environment.CurrentDirectory = orgDir;
                        NeonHelper.OpenEditorHandler = null;
                    }
                }
            }
        }
Exemplo n.º 16
0
        public async Task VaultPasswordName()
        {
            using (var testManager = new KubeTestManager())
            {
                using (var tempFolder = new TempFolder())
                {
                    var orgDir = Environment.CurrentDirectory;

                    Environment.CurrentDirectory = tempFolder.Path;
                    NeonHelper.OpenEditorHandler = path => File.WriteAllText(path, plainText);

                    try
                    {
                        using (var passwordFile = new TempFile(folder: KubeHelper.PasswordsFolder))
                        {
                            File.WriteAllText(passwordFile.Path, testPassword);

                            var vault = new NeonVault(passwordName => testPassword);

                            using (var runner = new ProgramRunner())
                            {
                                // Verify that the PATH argument is required.

                                var result = await runner.ExecuteAsync(Program.Main, "tool", "vault", "password-name");

                                Assert.NotEqual(0, result.ExitCode);
                                Assert.Contains("*** ERROR: The PATH argument is required.", result.ErrorText);

                                // Verify that we can create an encrypted file with an explicitly
                                // named password.

                                result = await runner.ExecuteAsync(Program.Main, "tool", "vault", "create", "test1.txt", passwordFile.Name);

                                Assert.Equal(0, result.ExitCode);
                                Assert.True(NeonVault.IsEncrypted("test1.txt", out var passwordName));
                                Assert.Equal(passwordFile.Name, passwordName);
                                Assert.Equal(plainText, Encoding.UTF8.GetString(vault.Decrypt("test1.txt")));

                                // Verify that we can get the password with a line ending.

                                result = await runner.ExecuteAsync(Program.Main, "tool", "vault", "password-name", "test1.txt", passwordFile.Name);

                                Assert.Equal(0, result.ExitCode);
                                Assert.Contains(passwordFile.Name, result.OutputText);
                                Assert.Contains('\n', result.OutputText);

                                // Verify that we can get the password without a line ending.

                                result = await runner.ExecuteAsync(Program.Main, "tool", "vault", "password-name", "-n", "test1.txt", passwordFile.Name);

                                Assert.Equal(0, result.ExitCode);
                                Assert.Equal(passwordFile.Name, result.OutputText);
                            }
                        }
                    }
                    finally
                    {
                        Environment.CurrentDirectory = orgDir;
                        NeonHelper.OpenEditorHandler = null;
                    }
                }
            }
        }
Exemplo n.º 17
0
        public async Task DecryptFile()
        {
            var orgDirectory = Environment.CurrentDirectory;

            try
            {
                using (var testManager = new KubeTestManager())
                {
                    using (var runner = new ProgramRunner())
                    {
                        using (var tempFolder = new TempFolder())
                        {
                            Environment.CurrentDirectory = tempFolder.Path;

                            var vault = new NeonVault(Program.LookupPassword);

                            // Create a test password and a [.password-name] file in the
                            // temp test folder.

                            var result = await runner.ExecuteAsync(Program.Main, "tool", "password", "set", "test");

                            Assert.Equal(0, result.ExitCode);

                            //-------------------------------------------------
                            // Verify that we can decrypt a file.

                            File.WriteAllText("test.cmd", "type %1 > output.txt");

                            const string plainText = "The quick brown fox jumped over the lazy dog.";

                            File.WriteAllText("file.txt", plainText);
                            File.WriteAllBytes("file.txt", vault.Encrypt("file.txt", "test"));
                            Assert.True(NeonVault.IsEncrypted("file.txt"));

                            result = await runner.ExecuteAsync(Program.Main, "tool", "run", "--", "test.cmd", "_...file.txt");

                            Assert.Equal(0, result.ExitCode);

                            var output = File.ReadAllText("output.txt");

                            Assert.Contains(plainText, output);
                            File.Delete("output.txt");
                            File.Delete("file.txt");

                            //-------------------------------------------------
                            // Try this again calling a command directly (batch files seem to have different behavior).

                            File.WriteAllText("type", "%1");

                            File.WriteAllText("file.txt", plainText);
                            File.WriteAllBytes("file.txt", vault.Encrypt("file.txt", "test"));
                            Assert.True(NeonVault.IsEncrypted("file.txt"));

                            result = await runner.ExecuteAsync(Program.Main, "tool", "run", "--", "cat", "_...file.txt");

                            Assert.Equal(0, result.ExitCode);

                            Assert.Contains(plainText, result.OutputText);
                            File.Delete("output.txt");
                            File.Delete("file.txt");
                        }
                    }
                }
            }
            finally
            {
                Environment.CurrentDirectory = orgDirectory;
            }
        }
Exemplo n.º 18
0
        public async Task VaultCreate()
        {
            using (var testManager = new KubeTestManager())
            {
                using (var tempFolder = new TempFolder())
                {
                    var orgDir = Environment.CurrentDirectory;

                    Environment.CurrentDirectory = tempFolder.Path;
                    NeonHelper.OpenEditorHandler = path => File.WriteAllText(path, plainText);

                    try
                    {
                        using (var passwordFile = new TempFile(folder: KubeHelper.PasswordsFolder))
                        {
                            File.WriteAllText(passwordFile.Path, testPassword);

                            var vault = new NeonVault(passwordName => testPassword);

                            using (var runner = new ProgramRunner())
                            {
                                // Verify that the PATH argument is required.

                                var result = await runner.ExecuteAsync(Program.Main, "tool", "vault", "create");

                                Assert.NotEqual(0, result.ExitCode);
                                Assert.Contains("*** ERROR: The PATH argument is required.", result.ErrorText);

                                // Verify that the PASSWORD-NAME argument is required when there's
                                // no default [.password-name] file.

                                result = await runner.ExecuteAsync(Program.Main, "tool", "vault", "create", "test1.txt");

                                Assert.NotEqual(0, result.ExitCode);
                                Assert.Contains("*** ERROR: A PASSWORD-NAME argument or [.password-name] file is required.", result.ErrorText);

                                // Verify that we can create an encrypted file with an explicitly
                                // named password.

                                result = await runner.ExecuteAsync(Program.Main, "tool", "vault", "create", "test2.txt", passwordFile.Name);

                                Assert.Equal(0, result.ExitCode);
                                Assert.True(NeonVault.IsEncrypted("test2.txt", out var passwordName));
                                Assert.Equal(passwordFile.Name, passwordName);
                                Assert.Equal(plainText, Encoding.UTF8.GetString(vault.Decrypt("test2.txt")));

                                // Verify that we see an error for a missing password.

                                result = await runner.ExecuteAsync(Program.Main, "tool", "vault", "create", "test3.txt", missingPasswordName);

                                Assert.NotEqual(0, result.ExitCode);
                                Assert.Contains($"*** ERROR: [System.Security.Cryptography.CryptographicException]: Password named [{missingPasswordName}] not found or is blank or whitespace.", result.ErrorText);

                                // Verify that we see an error for an invalid password.

                                result = await runner.ExecuteAsync(Program.Main, "tool", "vault", "create", "test4.txt", badPasswordName);

                                Assert.NotEqual(0, result.ExitCode);
                                Assert.Contains($"*** ERROR: [System.Security.Cryptography.CryptographicException]: Password name [bad/password] contains invalid characters.  Only ASCII letters, digits, underscores, dashs and dots are allowed.", result.ErrorText);

                                // Verify that a local [.password-name] file is used successfully when we don't
                                // explicitly pass a password name.

                                File.WriteAllText(".password-name", passwordFile.Name);

                                result = await runner.ExecuteAsync(Program.Main, "tool", "vault", "create", "test5.txt");

                                Assert.Equal(0, result.ExitCode);
                                Assert.True(NeonVault.IsEncrypted("test5.txt", out passwordName));
                                Assert.Equal(passwordFile.Name, passwordName);
                                Assert.Equal(plainText, Encoding.UTF8.GetString(vault.Decrypt("test5.txt")));

                                // Verify that a [.password-name] file in the parent directory is used successfully
                                // when we don't explicitly pass a password name.

                                Directory.CreateDirectory("subfolder");
                                Environment.CurrentDirectory = Path.Combine(Environment.CurrentDirectory, "subfolder");

                                result = await runner.ExecuteAsync(Program.Main, "tool", "vault", "create", "test6.txt");

                                Assert.Equal(0, result.ExitCode);
                                Assert.True(NeonVault.IsEncrypted("test6.txt", out passwordName));
                                Assert.Equal(passwordFile.Name, passwordName);
                                Assert.Equal(plainText, Encoding.UTF8.GetString(vault.Decrypt("test6.txt")));
                            }
                        }
                    }
                    finally
                    {
                        Environment.CurrentDirectory = orgDir;
                        NeonHelper.OpenEditorHandler = null;
                    }
                }
            }
        }
Exemplo n.º 19
0
        public async Task ReadVariables_Ecrypted()
        {
            var orgDirectory = Environment.CurrentDirectory;

            try
            {
                using (var testManager = new KubeTestManager())
                {
                    using (var runner = new ProgramRunner())
                    {
                        using (var tempFolder = new TempFolder())
                        {
                            Environment.CurrentDirectory = tempFolder.Path;

                            var vault = new NeonVault(Program.LookupPassword);

                            // Create a test password and a [.password-name] file in the
                            // temp test folder.

                            var result = await runner.ExecuteAsync(Program.Main, "tool", "password", "set", "test");

                            Assert.Equal(0, result.ExitCode);

                            File.WriteAllText(".password-name", "test");

                            //-------------------------------------------------
                            // Verify that we can read settings from a couple of
                            // ENCRYPTED variable files.

                            File.WriteAllText("test.cmd", "echo %* > output.txt");

                            File.WriteAllText("var1.txt",
                                              @"# This is a comment.

TEST_A=A-VALUE
TEST_B=B-VALUE
");
                            File.WriteAllBytes("var1.txt", vault.Encrypt("var1.txt", "test"));
                            Assert.True(NeonVault.IsEncrypted("var1.txt"));

                            File.WriteAllText("var2.txt",
                                              @"# This is a comment.

TEST_C=C-VALUE
TEST_D=D-VALUE
");
                            File.WriteAllBytes("var2.txt", vault.Encrypt("var2.txt", "test"));
                            Assert.True(NeonVault.IsEncrypted("var2.txt"));

                            result = await runner.ExecuteAsync(Program.Main, "tool", "run", "var1.txt", "var2.txt", "--", "test.cmd", "_.TEST_A", "_.TEST_B", "_.TEST_C", "_.TEST_D");

                            Assert.Equal(0, result.ExitCode);

                            var output = File.ReadAllText("output.txt");

                            Assert.Contains("A-VALUE", output);
                            Assert.Contains("B-VALUE", output);
                            Assert.Contains("C-VALUE", output);
                            Assert.Contains("D-VALUE", output);
                            File.Delete("output.txt");
                            File.Delete("var1.txt");
                            File.Delete("var2.txt");
                        }
                    }
                }
            }
            finally
            {
                Environment.CurrentDirectory = orgDirectory;
            }
        }