From 205fde5fc8dfac76e2c67b577ead38be7f94ea53 Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Sat, 18 Jun 2016 11:32:07 -0700 Subject: [PATCH] git: Implement encryption feature using new storage types --- SparkleShare/Linux/Setup.cs | 6 +++- Sparkles/Git/GitFetcher.cs | 55 ++++++++++++++++++++--------------- Sparkles/Git/GitRepository.cs | 44 +++++++++++++--------------- 3 files changed, 57 insertions(+), 48 deletions(-) diff --git a/SparkleShare/Linux/Setup.cs b/SparkleShare/Linux/Setup.cs index 9d01e0db..f186322a 100755 --- a/SparkleShare/Linux/Setup.cs +++ b/SparkleShare/Linux/Setup.cs @@ -185,7 +185,11 @@ namespace SparkleShare { Sensitive = (Controller.SelectedPreset.Path == null), ActivatesDefault = true }; - + + tree_view.ButtonReleaseEvent += delegate { + path_entry.GrabFocus (); + }; + Label address_example = new Label () { Xalign = 0, UseMarkup = true, diff --git a/Sparkles/Git/GitFetcher.cs b/Sparkles/Git/GitFetcher.cs index 1ada7e69..a699ce99 100644 --- a/Sparkles/Git/GitFetcher.cs +++ b/Sparkles/Git/GitFetcher.cs @@ -28,10 +28,11 @@ namespace Sparkles.Git { SSHAuthenticationInfo auth_info; GitCommand git_clone; + string password_salt = Path.GetRandomFileName ().SHA256 ().Substring (0, 16); + Regex progress_regex = new Regex (@"([0-9]+)%", RegexOptions.Compiled); Regex speed_regex = new Regex (@"([0-9\.]+) ([KM])iB/s", RegexOptions.Compiled); - string password_salt = "662282447f6bbb8c8e15fb32dd09e3e708c32bc8"; protected override bool IsFetchedRepoEmpty { @@ -91,11 +92,18 @@ namespace Sparkles.Git { return StorageType.Unknown; foreach (string line in output.Split ("\n".ToCharArray ())) { - if (line.Contains ("x-sparkleshare-lfs")) + string [] line_parts = line.Split ('/'); + string branch = line_parts [line_parts.Length - 1]; + + if (branch == "x-sparkleshare-lfs") return StorageType.Media; - if (line.Contains ("x-sparkleshare-encrypted")) + string encrypted_storage_prefix = "x-sparkleshare-encrypted-"; + + if (branch.StartsWith (encrypted_storage_prefix)) { + password_salt = branch.Replace (encrypted_storage_prefix, ""); return StorageType.Encrypted; + } } return StorageType.Plain; @@ -116,7 +124,7 @@ namespace Sparkles.Git { string git_clone_command = "clone --progress --no-checkout"; - if (FetchPriorHistory) + if (!FetchPriorHistory) git_clone_command += " --depth=1"; if (storage_type == StorageType.Media) @@ -258,10 +266,14 @@ namespace Sparkles.Git { public override void Complete (StorageType selected_storage_type) { - if (IsFetchedRepoEmpty) { - var git_commit = new GitCommand (TargetFolder, - "commit --allow-empty --mesage=\"Initial commit by SparkleShare\""); + base.Complete (selected_storage_type); + if (IsFetchedRepoEmpty) { + var git_add = new GitCommand (TargetFolder, "add .sparkleshare"); + var git_commit = new GitCommand (TargetFolder, "commit --message=\"Initial commit by SparkleShare\""); + + // We can't do the "commit --all" shortcut because it doesn't add untracked files + git_add.StartAndWaitForExit (); git_commit.StartAndWaitForExit (); // These branches will be pushed later by "git push --all" @@ -274,7 +286,9 @@ namespace Sparkles.Git { } if (selected_storage_type == StorageType.Encrypted) { - var git_branch = new GitCommand (TargetFolder, "branch x-sparkleshare-encrypted", auth_info); + var git_branch = new GitCommand (TargetFolder, + string.Format ("branch x-sparkleshare-encrypted-{0}", password_salt), auth_info); + git_branch.StartAndWaitForExit (); } @@ -291,11 +305,9 @@ namespace Sparkles.Git { if (git_show_ref.ExitCode == 0) branch = prefered_branch; - var git_checkout = new GitCommand (TargetFolder, "checkout --quiet " + branch); + var git_checkout = new GitCommand (TargetFolder, "checkout --quiet --force " + branch); git_checkout.StartAndWaitForExit (); } - - base.Complete (selected_storage_type); } @@ -329,17 +341,14 @@ namespace Sparkles.Git { public override void EnableFetchedRepoCrypto (string password) { + string password_file = ".git/info/encryption_password"; var git_config_required = new GitCommand (TargetFolder, "config filter.encryption.required true"); - var git_config_smudge = new GitCommand (TargetFolder, - "config filter.encryption.smudge \"openssl enc -d -aes-256-cbc -base64" + " " + - "-S " + password.SHA256 (password_salt).Substring (0, 16) + " " + - "-pass file:.git/info/encryption_password\""); + var git_config_smudge = new GitCommand (TargetFolder, "config filter.encryption.smudge " + + string.Format ("\"openssl enc -d -aes-256-cbc -base64 -S {0} -pass file:{1}\"", password_salt, password_file)); - var git_config_clean = new GitCommand (TargetFolder, - "config filter.encryption.clean \"openssl enc -e -aes-256-cbc -base64" + " " + - "-S " + password.SHA256 (password_salt).Substring (0, 16) + " " + - "-pass file:.git/info/encryption_password\""); + var git_config_clean = new GitCommand (TargetFolder, "config filter.encryption.clean " + + string.Format ("\"openssl enc -e -aes-256-cbc -base64 -S {0} -pass file:{1}\"", password_salt, password_file)); git_config_required.StartAndWaitForExit (); git_config_smudge.StartAndWaitForExit (); @@ -348,7 +357,7 @@ namespace Sparkles.Git { // Pass all files through the encryption filter // TODO: diff=encryption merge=encryption -text? string git_attributes_file_path = Path.Combine (TargetFolder, ".git", "info", "attributes"); - File.WriteAllText (git_attributes_file_path, "* filter=encryption"); + File.WriteAllText (git_attributes_file_path, "* filter=encryption diff=encryption merge=encryption -text"); // Store the password string password_file_path = Path.Combine (TargetFolder, ".git", "info", "encryption_password"); @@ -370,12 +379,12 @@ namespace Sparkles.Git { return false; } - string args = "enc -d -aes-256-cbc -base64 -salt -pass pass:" + password.SHA256 (password_salt) + " " + - "-in \"" + password_check_file_path + "\""; + string args = string.Format ("enc -d -aes-256-cbc -base64 -S {0} -pass pass:{1} -in \"{2}\"", + password_salt, password.SHA256 (password_salt), password_check_file_path); var process = new Command ("openssl", args); - process.StartInfo.WorkingDirectory = TargetFolder; + process.StartInfo.WorkingDirectory = TargetFolder; process.StartAndWaitForExit (); if (process.ExitCode == 0) { diff --git a/Sparkles/Git/GitRepository.cs b/Sparkles/Git/GitRepository.cs index f97b23c9..13b034a6 100644 --- a/Sparkles/Git/GitRepository.cs +++ b/Sparkles/Git/GitRepository.cs @@ -29,26 +29,10 @@ namespace Sparkles.Git { SSHAuthenticationInfo auth_info; bool user_is_set; - bool is_encrypted; + string cached_branch; - Regex progress_regex = new Regex (@"([0-9]+)%", RegexOptions.Compiled); - Regex speed_regex = new Regex (@"([0-9\.]+) ([KM])iB/s", RegexOptions.Compiled); - - Regex log_regex = new Regex (@"commit ([a-f0-9]{40})*\n" + - "Author: (.+) <(.+)>\n" + - "Date: ([0-9]{4})-([0-9]{2})-([0-9]{2}) " + - "([0-9]{2}):([0-9]{2}):([0-9]{2}) (.[0-9]{4})\n" + - "*", RegexOptions.Compiled); - - Regex merge_regex = new Regex (@"commit ([a-f0-9]{40})\n" + - "Merge: [a-f0-9]{7} [a-f0-9]{7}\n" + - "Author: (.+) <(.+)>\n" + - "Date: ([0-9]{4})-([0-9]{2})-([0-9]{2}) " + - "([0-9]{2}):([0-9]{2}):([0-9]{2}) (.[0-9]{4})\n" + - "*", RegexOptions.Compiled); - string branch { get { if (!string.IsNullOrEmpty (this.cached_branch)) @@ -95,11 +79,6 @@ namespace Sparkles.Git { git_config = new GitCommand (LocalPath, "config remote.origin.url \"" + RemoteUrl + "\""); git_config.StartAndWaitForExit (); - - string password_file_path = Path.Combine (LocalPath, ".git", "password"); - - if (File.Exists (password_file_path)) - this.is_encrypted = true; } @@ -177,7 +156,7 @@ namespace Sparkles.Git { var git = new GitCommand (LocalPath, "ls-remote --heads --exit-code \"" + RemoteUrl + "\" " + this.branch, auth_info); - string output = git.StartAndReadStandardOutput (); + string output = git.StartAndReadStandardOutput (); if (git.ExitCode != 0) return false; @@ -651,7 +630,7 @@ namespace Sparkles.Git { // git-show doesn't decrypt objects, so we can't use it to retrieve // files from the index. This is a suboptimal workaround but it does the job - if (this.is_encrypted) { + if (StorageType == StorageType.Encrypted) { // Restore the older file... var git = new GitCommand (LocalPath, "checkout " + revision + " \"" + path + "\""); git.StartAndWaitForExit (); @@ -1179,5 +1158,22 @@ namespace Sparkles.Git { FileAttributes attributes = File.GetAttributes (file); return ((attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint); } + + + Regex progress_regex = new Regex (@"([0-9]+)%", RegexOptions.Compiled); + Regex speed_regex = new Regex (@"([0-9\.]+) ([KM])iB/s", RegexOptions.Compiled); + + Regex log_regex = new Regex (@"commit ([a-f0-9]{40})*\n" + + "Author: (.+) <(.+)>\n" + + "Date: ([0-9]{4})-([0-9]{2})-([0-9]{2}) " + + "([0-9]{2}):([0-9]{2}):([0-9]{2}) (.[0-9]{4})\n" + + "*", RegexOptions.Compiled); + + Regex merge_regex = new Regex (@"commit ([a-f0-9]{40})\n" + + "Merge: [a-f0-9]{7} [a-f0-9]{7}\n" + + "Author: (.+) <(.+)>\n" + + "Date: ([0-9]{4})-([0-9]{2})-([0-9]{2}) " + + "([0-9]{2}):([0-9]{2}):([0-9]{2}) (.[0-9]{4})\n" + + "*", RegexOptions.Compiled); } }