SparkleShare/Sparkles/SSHAuthenticationInfo.cs

129 lines
4.3 KiB
C#

// SparkleShare, a collaboration and sharing tool.
// Copyright (C) 2010 Hylke Bons <hi@planetpeanut.uk>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Net;
using IO = System.IO;
namespace Sparkles {
public class SSHAuthenticationInfo : AuthenticationInfo {
public static SSHAuthenticationInfo DefaultAuthenticationInfo;
public string PrivateKeyFilePath { get; private set; }
public string PrivateKey { get; private set; }
public string PublicKeyFilePath { get; private set; }
public string PublicKey { get; private set; }
public string KnownHostsFilePath { get; private set; }
readonly string Path;
public SSHAuthenticationInfo ()
{
Path = IO.Path.Combine (Configuration.DefaultConfiguration.DirectoryPath, "ssh");
KnownHostsFilePath = IO.Path.Combine (Path, "known_hosts");
KnownHostsFilePath = MakeWindowsDomainAccountSafe (KnownHostsFilePath);
if (IO.Directory.Exists (Path)) {
ImportKeys ();
} else {
IO.Directory.CreateDirectory (Path);
CreateKeyPair ();
}
}
void ImportKeys ()
{
bool key_found = false;
foreach (string file_path in IO.Directory.GetFiles (Path)) {
if (file_path.EndsWith (".key", StringComparison.InvariantCultureIgnoreCase)) {
PrivateKeyFilePath = file_path;
PublicKeyFilePath = file_path + ".pub";
key_found = true;
break;
}
}
if (key_found) {
PrivateKeyFilePath = MakeWindowsDomainAccountSafe (PrivateKeyFilePath);
PublicKeyFilePath = MakeWindowsDomainAccountSafe (PublicKeyFilePath);
PrivateKey = IO.File.ReadAllText (PrivateKeyFilePath);
PublicKey = IO.File.ReadAllText (PublicKeyFilePath);
} else {
CreateKeyPair ();
ImportKeys ();
}
}
bool CreateKeyPair ()
{
string key_file_name = DateTime.Now.ToString ("yyyy-MM-dd_HH\\hmm") + ".key";
string computer_name = Dns.GetHostName ();
if (computer_name.EndsWith (".local", StringComparison.InvariantCultureIgnoreCase) ||
computer_name.EndsWith (".config", StringComparison.InvariantCultureIgnoreCase))
computer_name = computer_name.Substring (0,
computer_name.LastIndexOf (".", StringComparison.InvariantCulture));
string arguments =
"-t rsa " + // Crypto type
"-b 4096 " + // Key size
"-P \"\" " + // No password
"-C \"" + computer_name + " (SparkleShare)\" " + // Key comment
"-f \"" + key_file_name + "\"";
var ssh_keygen = new SSHCommand ("ssh-keygen", arguments);
ssh_keygen.StartInfo.WorkingDirectory = Path;
ssh_keygen.StartAndWaitForExit ();
if (ssh_keygen.ExitCode == 0) {
Logger.LogInfo ("Auth", "Created key pair: " + key_file_name);
ImportKeys ();
return true;
}
Logger.LogInfo ("Auth", "Could not create key pair");
return false;
}
// Use forward slashes in paths when dealing with Windows domain accounts
string MakeWindowsDomainAccountSafe (string path)
{
if (path.StartsWith ("\\\\", StringComparison.InvariantCulture))
return path.Replace ("\\", "/");
return path;
}
}
}