From 1c02a4f7e8acc25607d92eedb2fc8654d1aed377 Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Wed, 13 Feb 2013 22:45:12 +0000 Subject: [PATCH 1/6] windows: explicitly point GIT_SSH to ssh.exe --- SparkleLib/Git/SparkleGit.cs | 4 ++++ SparkleShare/Windows/SparkleController.cs | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/SparkleLib/Git/SparkleGit.cs b/SparkleLib/Git/SparkleGit.cs index c2b14930..7c71cf28 100644 --- a/SparkleLib/Git/SparkleGit.cs +++ b/SparkleLib/Git/SparkleGit.cs @@ -103,6 +103,7 @@ namespace SparkleLib.Git { public static string ExecPath; public static string GitPath; + public static string SSHPath; public SparkleGit (string path, string args) : base (path, args) @@ -117,6 +118,9 @@ namespace SparkleLib.Git { StartInfo.WorkingDirectory = path; StartInfo.CreateNoWindow = true; + if (!string.IsNullOrEmpty (SSHPath)) + StartInfo.EnvironmentVariables.Add ("GIT_SSH", SSHPath); + if (string.IsNullOrEmpty (ExecPath)) StartInfo.Arguments = args; else diff --git a/SparkleShare/Windows/SparkleController.cs b/SparkleShare/Windows/SparkleController.cs index 60ad3e90..8dc7aca6 100644 --- a/SparkleShare/Windows/SparkleController.cs +++ b/SparkleShare/Windows/SparkleController.cs @@ -29,6 +29,7 @@ using Forms = System.Windows.Forms; using Microsoft.Win32; using SparkleLib; + namespace SparkleShare { public class SparkleController : SparkleControllerBase { @@ -56,6 +57,7 @@ namespace SparkleShare { string executable_path = Path.GetDirectoryName (Forms.Application.ExecutablePath); string msysgit_path = Path.Combine (executable_path, "msysgit"); + string new_PATH = msysgit_path + @"\bin" + ";" + msysgit_path + @"\mingw\bin" + ";" + msysgit_path + @"\cmd" + ";" + @@ -65,6 +67,8 @@ namespace SparkleShare { Environment.SetEnvironmentVariable ("HOME", Environment.GetFolderPath (Environment.SpecialFolder.UserProfile)); StartSSH (); + SparkleLib.Git.SparkleGit.SSHPath = Path.Combine (msysgit_path, "ssh.exe"); + base.Initialize (); } From 75e8a17d8a22ca9e596c62ad54d28595272e6f38 Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Mon, 11 Mar 2013 21:01:41 +0000 Subject: [PATCH 2/6] git: only add GIT_SSH env var if it doesn't exist already --- SparkleLib/Git/SparkleGit.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/SparkleLib/Git/SparkleGit.cs b/SparkleLib/Git/SparkleGit.cs index 7c71cf28..250b2674 100644 --- a/SparkleLib/Git/SparkleGit.cs +++ b/SparkleLib/Git/SparkleGit.cs @@ -118,8 +118,12 @@ namespace SparkleLib.Git { StartInfo.WorkingDirectory = path; StartInfo.CreateNoWindow = true; - if (!string.IsNullOrEmpty (SSHPath)) - StartInfo.EnvironmentVariables.Add ("GIT_SSH", SSHPath); + if (!string.IsNullOrEmpty (SSHPath)) { + if (StartInfo.EnvironmentVariables.ContainsKey ("GIT_SSH")) + StartInfo.EnvironmentVariables ["GIT_SSH"] = SSHPath; + else + StartInfo.EnvironmentVariables.Add ("GIT_SSH", SSHPath); + } if (string.IsNullOrEmpty (ExecPath)) StartInfo.Arguments = args; From e7dd253db99dff57c59a53840accda92a47cace8 Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Mon, 18 Mar 2013 12:35:06 +0100 Subject: [PATCH 3/6] windows: fix build --- SparkleShare/Windows/SparkleController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SparkleShare/Windows/SparkleController.cs b/SparkleShare/Windows/SparkleController.cs index 8dc7aca6..fefcaf82 100644 --- a/SparkleShare/Windows/SparkleController.cs +++ b/SparkleShare/Windows/SparkleController.cs @@ -67,7 +67,7 @@ namespace SparkleShare { Environment.SetEnvironmentVariable ("HOME", Environment.GetFolderPath (Environment.SpecialFolder.UserProfile)); StartSSH (); - SparkleLib.Git.SparkleGit.SSHPath = Path.Combine (msysgit_path, "ssh.exe"); + SparkleLib.SparkleGit.SparkleGit.SSHPath = Path.Combine (msysgit_path, "ssh.exe"); base.Initialize (); } From fee24420c748982697bc39f2b0d7f4be68899ebc Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Sat, 23 Mar 2013 18:48:47 +0100 Subject: [PATCH 4/6] plugins: respect the Backend element. closes #1224 --- SparkleLib/SparkleFetcherBase.cs | 3 ++- SparkleShare/SparkleControllerBase.cs | 6 +++++- SparkleShare/SparklePlugin.cs | 2 +- SparkleShare/SparkleSetupController.cs | 3 ++- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/SparkleLib/SparkleFetcherBase.cs b/SparkleLib/SparkleFetcherBase.cs index 60919134..15deb390 100755 --- a/SparkleLib/SparkleFetcherBase.cs +++ b/SparkleLib/SparkleFetcherBase.cs @@ -26,8 +26,9 @@ namespace SparkleLib { public class SparkleFetcherInfo { public string Address; - public string Fingerprint; public string RemotePath; + public string Backend; + public string Fingerprint; public string TargetDirectory; public string AnnouncementsUrl; public bool FetchPriorHistory; diff --git a/SparkleShare/SparkleControllerBase.cs b/SparkleShare/SparkleControllerBase.cs index 8ea3de68..9a26682f 100644 --- a/SparkleShare/SparkleControllerBase.cs +++ b/SparkleShare/SparkleControllerBase.cs @@ -542,7 +542,11 @@ namespace SparkleShare { } string canonical_name = Path.GetFileName (info.RemotePath); - string backend = SparkleFetcherBase.GetBackend (info.Address); + string backend = info.Backend; + + if (string.IsNullOrEmpty (backend)) + backend = SparkleFetcherBase.GetBackend (info.Address); + info.TargetDirectory = Path.Combine (tmp_path, canonical_name); try { diff --git a/SparkleShare/SparklePlugin.cs b/SparkleShare/SparklePlugin.cs index 07a6548a..c80d2d8a 100644 --- a/SparkleShare/SparklePlugin.cs +++ b/SparkleShare/SparklePlugin.cs @@ -43,7 +43,7 @@ namespace SparkleShare { get { string image_file_name = GetValue ("info", "icon"); string image_path = IO.Path.Combine (this.plugin_directory, image_file_name); - + if (IO.File.Exists (image_path)) return image_path; else diff --git a/SparkleShare/SparkleSetupController.cs b/SparkleShare/SparkleSetupController.cs index e5391f1c..79cef7ec 100755 --- a/SparkleShare/SparkleSetupController.cs +++ b/SparkleShare/SparkleSetupController.cs @@ -376,7 +376,8 @@ namespace SparkleShare { Fingerprint = SelectedPlugin.Fingerprint, RemotePath = remote_path, FetchPriorHistory = this.fetch_prior_history, - AnnouncementsUrl = SelectedPlugin.AnnouncementsUrl + AnnouncementsUrl = SelectedPlugin.AnnouncementsUrl, + Backend = SelectedPlugin.Backend }; new Thread (() => { Program.Controller.StartFetcher (info); }).Start (); From ac879068e5cabc68e64a7d2854bd7fdd57cab51b Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Sun, 24 Mar 2013 23:52:05 +0100 Subject: [PATCH 5/6] fetcher: create separate Base, SSH, and Git classes. cleaner abstraction. --- SparkleLib/Defines.cs | 2 +- SparkleLib/Git/SparkleFetcherGit.cs | 20 +--- SparkleLib/Makefile.am | 1 + SparkleLib/SparkleFetcherBase.cs | 127 +----------------------- SparkleLib/SparkleFetcherSSH.cs | 138 ++++++++++++++++++++++++++ SparkleLib/SparkleLib.csproj | 1 + SparkleShare/SparkleControllerBase.cs | 7 -- 7 files changed, 145 insertions(+), 151 deletions(-) create mode 100644 SparkleLib/SparkleFetcherSSH.cs diff --git a/SparkleLib/Defines.cs b/SparkleLib/Defines.cs index f87c80e4..037291a4 100644 --- a/SparkleLib/Defines.cs +++ b/SparkleLib/Defines.cs @@ -26,6 +26,6 @@ using System.Reflection; namespace SparkleLib { public class Defines { - public const string INSTALL_DIR = "/usr/share/sparkleshare"; + public const string INSTALL_DIR = "/usr/local/share/sparkleshare"; } } diff --git a/SparkleLib/Git/SparkleFetcherGit.cs b/SparkleLib/Git/SparkleFetcherGit.cs index 82c8dd3d..127c1381 100755 --- a/SparkleLib/Git/SparkleFetcherGit.cs +++ b/SparkleLib/Git/SparkleFetcherGit.cs @@ -25,8 +25,7 @@ using SparkleLib; namespace SparkleLib.Git { - // Sets up a fetcher that can get remote folders - public class SparkleFetcher : SparkleFetcherBase { + public class SparkleFetcher : SparkleFetcherSSH { private SparkleGit git; private bool use_git_bin; @@ -188,8 +187,6 @@ namespace SparkleLib.Git { InstallExcludeRules (); InstallAttributeRules (); - AddWarnings (); - return true; } else { @@ -386,20 +383,5 @@ namespace SparkleLib.Git { writer.Close (); } - - - private void AddWarnings () - { - if (this.warnings.Count > 0) - return; - - SparkleGit git = new SparkleGit (TargetFolder, "config --global core.excludesfile"); - string output = git.StartAndReadStandardOutput (); - - if (string.IsNullOrEmpty (output)) - return; - else - this.warnings.Add ("You seem to have a system wide ‘gitignore’ file, this may affect SparkleShare files."); - } } } diff --git a/SparkleLib/Makefile.am b/SparkleLib/Makefile.am index da03327b..55fad6cd 100755 --- a/SparkleLib/Makefile.am +++ b/SparkleLib/Makefile.am @@ -9,6 +9,7 @@ SOURCES = \ SparkleConfig.cs \ SparkleExtensions.cs \ SparkleFetcherBase.cs \ + SparkleFetcherSSH.cs \ SparkleListenerBase.cs \ SparkleListenerFactory.cs \ SparkleListenerTcp.cs \ diff --git a/SparkleLib/SparkleFetcherBase.cs b/SparkleLib/SparkleFetcherBase.cs index 15deb390..80b33dee 100755 --- a/SparkleLib/SparkleFetcherBase.cs +++ b/SparkleLib/SparkleFetcherBase.cs @@ -132,44 +132,9 @@ namespace SparkleLib { SparkleLogger.LogInfo ("Fetcher", TargetFolder + " | Fetching folder: " + RemoteUrl); - if (Directory.Exists (TargetFolder)) + if (Directory.Exists (TargetFolder)) Directory.Delete (TargetFolder, true); - string host_key = ""; - - if (!RemoteUrl.Scheme.StartsWith ("http")) { - host_key = FetchHostKey (); - - if (string.IsNullOrEmpty (RemoteUrl.Host) || host_key == null) { - SparkleLogger.LogInfo ("Auth", "Could not fetch host key"); - Failed (); - - return; - } - - bool warn = true; - if (RequiredFingerprint != null) { - string host_fingerprint = DeriveFingerprint (host_key); - - if (host_fingerprint == null || !RequiredFingerprint.Equals (host_fingerprint)) { - SparkleLogger.LogInfo ("Auth", "Fingerprint doesn't match"); - - this.errors.Add ("error: Host fingerprint doesn't match"); - Failed (); - - return; - } - - warn = false; - SparkleLogger.LogInfo ("Auth", "Fingerprint matches"); - - } else { - SparkleLogger.LogInfo ("Auth", "Skipping fingerprint check"); - } - - AcceptHostKey (host_key, warn); - } - this.thread = new Thread (() => { if (Fetch ()) { Thread.Sleep (500); @@ -222,7 +187,7 @@ namespace SparkleLib { UriBuilder uri_builder = new UriBuilder (RemoteUrl); - if (RemoteUrl.Scheme.StartsWith ("http")) { + if (RemoteUrl.Scheme.Contains ("http")) { uri_builder.UserName = ""; uri_builder.Password = ""; } @@ -246,8 +211,7 @@ namespace SparkleLib { public static string CreateIdentifier () { - string random = Path.GetRandomFileName (); - return random.SHA1 (); + return Path.GetRandomFileName ().SHA1 (); } @@ -270,91 +234,6 @@ namespace SparkleLib { } - private string FetchHostKey () - { - SparkleLogger.LogInfo ("Auth", "Fetching host key for " + RemoteUrl.Host); - - Process process = new Process (); - process.StartInfo.FileName = "ssh-keyscan"; - process.StartInfo.WorkingDirectory = SparkleConfig.DefaultConfig.TmpPath; - process.StartInfo.UseShellExecute = false; - process.StartInfo.RedirectStandardOutput = true; - process.StartInfo.CreateNoWindow = true; - process.EnableRaisingEvents = true; - - string [] key_types = {"rsa", "dsa", "ecdsa"}; - - foreach (string key_type in key_types) { - if (RemoteUrl.Port < 1) - process.StartInfo.Arguments = "-t " + key_type + " -p 22 " + RemoteUrl.Host; - else - process.StartInfo.Arguments = "-t " + key_type + " -p " + RemoteUrl.Port + " " + RemoteUrl.Host; - - SparkleLogger.LogInfo ("Cmd", process.StartInfo.FileName + " " + process.StartInfo.Arguments); - - process.Start (); - string host_key = process.StandardOutput.ReadToEnd ().Trim (); - process.WaitForExit (); - - if (process.ExitCode == 0 && !string.IsNullOrWhiteSpace (host_key)) - return host_key; - } - - return null; - } - - - private string DeriveFingerprint (string public_key) - { - try { - MD5 md5 = new MD5CryptoServiceProvider (); - string key = public_key.Split (" ".ToCharArray ()) [2]; - byte [] b64_bytes = Convert.FromBase64String (key); - byte [] md5_bytes = md5.ComputeHash (b64_bytes); - string fingerprint = BitConverter.ToString (md5_bytes); - - return fingerprint.ToLower ().Replace ("-", ":"); - - } catch (Exception e) { - SparkleLogger.LogInfo ("Fetcher", "Failed creating fingerprint: " + e.Message + " " + e.StackTrace); - return null; - } - } - - - private void AcceptHostKey (string host_key, bool warn) - { - string ssh_config_path = Path.Combine (SparkleConfig.DefaultConfig.HomePath, ".ssh"); - string known_hosts_file_path = Path.Combine (ssh_config_path, "known_hosts"); - - if (!File.Exists (known_hosts_file_path)) { - if (!Directory.Exists (ssh_config_path)) - Directory.CreateDirectory (ssh_config_path); - - File.Create (known_hosts_file_path).Close (); - } - - string host = RemoteUrl.Host; - string known_hosts = File.ReadAllText (known_hosts_file_path); - string [] known_hosts_lines = File.ReadAllLines (known_hosts_file_path); - - foreach (string line in known_hosts_lines) { - if (line.StartsWith (host + " ")) - return; - } - - if (known_hosts.EndsWith ("\n")) - File.AppendAllText (known_hosts_file_path, host_key + "\n"); - else - File.AppendAllText (known_hosts_file_path, "\n" + host_key + "\n"); - - SparkleLogger.LogInfo ("Auth", "Accepted host key for " + host); - - if (warn) - this.warnings.Add ("The following host key has been accepted:\n" + DeriveFingerprint (host_key)); - } - - public static string GetBackend (string address) { if (address.StartsWith ("ssh+")) { diff --git a/SparkleLib/SparkleFetcherSSH.cs b/SparkleLib/SparkleFetcherSSH.cs new file mode 100644 index 00000000..33fdc3cd --- /dev/null +++ b/SparkleLib/SparkleFetcherSSH.cs @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Security.Cryptography; +using System.Threading; + +namespace SparkleLib { + + public abstract class SparkleFetcherSSH : SparkleFetcherBase { + + public SparkleFetcherSSH (SparkleFetcherInfo info) : base (info) + { + } + + + public override bool Fetch () + { + if (!RemoteUrl.Scheme.StartsWith ("http")) { + string host_key = FetchHostKey (); + + if (string.IsNullOrEmpty (RemoteUrl.Host) || host_key == null) { + SparkleLogger.LogInfo ("Auth", "Could not fetch host key"); + this.errors.Add ("error: Could not fetch host key"); + + return false; + } + + bool warn = true; + if (RequiredFingerprint != null) { + string host_fingerprint = DeriveFingerprint (host_key); + + if (host_fingerprint == null || !RequiredFingerprint.Equals (host_fingerprint)) { + SparkleLogger.LogInfo ("Auth", "Fingerprint doesn't match"); + this.errors.Add ("error: Host fingerprint doesn't match"); + + return false; + } + + warn = false; + SparkleLogger.LogInfo ("Auth", "Fingerprint matches"); + + } else { + SparkleLogger.LogInfo ("Auth", "Skipping fingerprint check"); + } + + AcceptHostKey (host_key, warn); + } + + return true; + } + + + private string FetchHostKey () + { + SparkleLogger.LogInfo ("Auth", "Fetching host key for " + RemoteUrl.Host); + + Process process = new Process (); + process.StartInfo.FileName = "ssh-keyscan"; + process.StartInfo.WorkingDirectory = SparkleConfig.DefaultConfig.TmpPath; + process.StartInfo.UseShellExecute = false; + process.StartInfo.RedirectStandardOutput = true; + process.StartInfo.CreateNoWindow = true; + process.EnableRaisingEvents = true; + + string [] key_types = {"rsa", "dsa", "ecdsa"}; + + foreach (string key_type in key_types) { + if (RemoteUrl.Port < 1) + process.StartInfo.Arguments = "-t " + key_type + " -p 22 " + RemoteUrl.Host; + else + process.StartInfo.Arguments = "-t " + key_type + " -p " + RemoteUrl.Port + " " + RemoteUrl.Host; + + SparkleLogger.LogInfo ("Cmd", process.StartInfo.FileName + " " + process.StartInfo.Arguments); + + process.Start (); + string host_key = process.StandardOutput.ReadToEnd ().Trim (); + process.WaitForExit (); + + if (process.ExitCode == 0 && !string.IsNullOrWhiteSpace (host_key)) + return host_key; + } + + return null; + } + + + private string DeriveFingerprint (string public_key) + { + try { + MD5 md5 = new MD5CryptoServiceProvider (); + string key = public_key.Split (" ".ToCharArray ()) [2]; + byte [] b64_bytes = Convert.FromBase64String (key); + byte [] md5_bytes = md5.ComputeHash (b64_bytes); + string fingerprint = BitConverter.ToString (md5_bytes); + + return fingerprint.ToLower ().Replace ("-", ":"); + + } catch (Exception e) { + SparkleLogger.LogInfo ("Fetcher", "Failed creating fingerprint: " + e.Message + " " + e.StackTrace); + return null; + } + } + + + private void AcceptHostKey (string host_key, bool warn) + { + string ssh_config_path = Path.Combine (SparkleConfig.DefaultConfig.HomePath, ".ssh"); + string known_hosts_file_path = Path.Combine (ssh_config_path, "known_hosts"); + + if (!File.Exists (known_hosts_file_path)) { + if (!Directory.Exists (ssh_config_path)) + Directory.CreateDirectory (ssh_config_path); + + File.Create (known_hosts_file_path).Close (); + } + + string host = RemoteUrl.Host; + string known_hosts = File.ReadAllText (known_hosts_file_path); + string [] known_hosts_lines = File.ReadAllLines (known_hosts_file_path); + + foreach (string line in known_hosts_lines) { + if (line.StartsWith (host + " ")) + return; + } + + if (known_hosts.EndsWith ("\n")) + File.AppendAllText (known_hosts_file_path, host_key + "\n"); + else + File.AppendAllText (known_hosts_file_path, "\n" + host_key + "\n"); + + SparkleLogger.LogInfo ("Auth", "Accepted host key for " + host); + + if (warn) + this.warnings.Add ("The following host key has been accepted:\n" + DeriveFingerprint (host_key)); + } + } +} diff --git a/SparkleLib/SparkleLib.csproj b/SparkleLib/SparkleLib.csproj index 8b7c4ada..fb1fcc98 100644 --- a/SparkleLib/SparkleLib.csproj +++ b/SparkleLib/SparkleLib.csproj @@ -43,6 +43,7 @@ + diff --git a/SparkleShare/SparkleControllerBase.cs b/SparkleShare/SparkleControllerBase.cs index 9a26682f..89a9ac6f 100644 --- a/SparkleShare/SparkleControllerBase.cs +++ b/SparkleShare/SparkleControllerBase.cs @@ -211,13 +211,6 @@ namespace SparkleShare { else name += "'s"; - string link_code_file_path = Path.Combine (FoldersPath, name + " link code.txt"); - - // Create an easily accessible copy of the public - // key in the user's SparkleShare folder - if (File.Exists (public_key_file_path) && !File.Exists (link_code_file_path)) - File.Copy (public_key_file_path, link_code_file_path, true); - CurrentUser.PublicKey = File.ReadAllText (public_key_file_path); } From ea34e9680654856f7f3947f4e87bbba49060de4f Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Sun, 23 Jun 2013 09:58:55 +0100 Subject: [PATCH 6/6] windows: Fix GIT_SSH path to ssh.exe --- SparkleShare/Windows/SparkleController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SparkleShare/Windows/SparkleController.cs b/SparkleShare/Windows/SparkleController.cs index fefcaf82..da0fb9d8 100644 --- a/SparkleShare/Windows/SparkleController.cs +++ b/SparkleShare/Windows/SparkleController.cs @@ -67,7 +67,7 @@ namespace SparkleShare { Environment.SetEnvironmentVariable ("HOME", Environment.GetFolderPath (Environment.SpecialFolder.UserProfile)); StartSSH (); - SparkleLib.SparkleGit.SparkleGit.SSHPath = Path.Combine (msysgit_path, "ssh.exe"); + SparkleLib.SparkleGit.SparkleGit.SSHPath = Path.Combine (msysgit_path, "bin", "ssh.exe"); base.Initialize (); }