git: Implement encryption feature using new storage types

This commit is contained in:
Hylke Bons 2016-06-18 11:32:07 -07:00 committed by Hylke Bons
parent 9a0848b305
commit 205fde5fc8
3 changed files with 57 additions and 48 deletions

View file

@ -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,

View file

@ -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) {

View file

@ -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);
}
}