Пример #1
0
        /// <summary>
        /// Creates a <see cref="SshProxy{TMetadata}"/> for the specified host and server name,
        /// configuring logging and the credentials as specified by the global command
        /// line options.
        /// </summary>
        /// <param name="name">The node name.</param>
        /// <param name="publicAddress">The node's public IP address or FQDN.</param>
        /// <param name="privateAddress">The node's private IP address.</param>
        /// <param name="appendToLog">
        /// Pass <c>true</c> to append to an existing log file (or create one if necessary)
        /// or <c>false</c> to replace any existing log file with a new one.
        /// </param>
        ///
        /// <typeparam name="TMetadata">Defines the metadata type the command wishes to associate with the server.</typeparam>
        /// <returns>The <see cref="SshProxy{TMetadata}"/>.</returns>
        public static SshProxy <TMetadata> CreateNodeProxy <TMetadata>(string name, string publicAddress, IPAddress privateAddress, bool appendToLog)
            where TMetadata : class
        {
            Covenant.Requires <ArgumentNullException>(!string.IsNullOrEmpty(name));

            var logWriter = (TextWriter)null;

            if (!string.IsNullOrEmpty(LogPath))
            {
                var path = Path.Combine(LogPath, name + ".log");

                logWriter = new StreamWriter(new FileStream(path, appendToLog ? FileMode.Append : FileMode.Create, appendToLog ? FileAccess.Write : FileAccess.ReadWrite));
            }

            SshCredentials sshCredentials;

            if (!string.IsNullOrEmpty(Program.MachineUsername) && !string.IsNullOrEmpty(Program.MachinePassword))
            {
                sshCredentials = SshCredentials.FromUserPassword(Program.MachineUsername, Program.MachinePassword);
            }
            else if (KubeHelper.CurrentContext != null)
            {
                sshCredentials = KubeHelper.CurrentContext.Extension.SshCredentials;
            }
            else
            {
                Console.Error.WriteLine("*** ERROR: Expected some node credentials.");
                Program.Exit(1);

                return(null);
            }

            return(new SshProxy <TMetadata>(name, publicAddress, privateAddress, sshCredentials, logWriter));
        }
Пример #2
0
        /// <summary>
        /// Establishes an SSH connection to the assocated XenServer.
        /// </summary>
        /// <returns>The connected <see cref="LinuxSshProxy"/>.</returns>
        public LinuxSshProxy Connect()
        {
            var proxy = new LinuxSshProxy(Name, IPAddress.Parse(Address), SshCredentials.FromUserPassword(username, password));

            proxy.Connect();

            return(proxy);
        }
Пример #3
0
        public static void Init(TestContext context)
        {
            string settingsFile = "./SshCredentials.json";

            if (!File.Exists(settingsFile))
            {
                File.WriteAllText(settingsFile, JsonConvert.SerializeObject(new SshCredentials()));
                throw new FileNotFoundException("Файл настроек не найден, однако был создан файл настроек по-умолчанию в папке с программой. Заполните его параметры.");
            }
            _SshCredentials = JsonConvert.DeserializeObject <SshCredentials>(File.ReadAllText(settingsFile));
            RandomNumber    = new Random().Next(10000, 99999);
        }
Пример #4
0
        public static SshTunnel Open(string hostname, SshCredentials credentials, int port = 22)
        {
            List <AuthenticationMethod> authenticationMethods = new List <AuthenticationMethod>();

            if (credentials.HasPassword)
            {
                authenticationMethods.Add(new PasswordAuthenticationMethod(credentials.Username, credentials.Password));
            }
            if (credentials.HasPrivateKeyFile)
            {
                authenticationMethods.Add(new PrivateKeyAuthenticationMethod(credentials.PrivateKeyFile));
            }

            ConnectionInfo connectionInfo = new ConnectionInfo(hostname, port, credentials.Username, authenticationMethods.ToArray());

            SshClient client = new SshClient(connectionInfo);

            client.Connect();

            return(new SshTunnel(client));
        }
Пример #5
0
 public Service(SshCredentials ssh)
 {
     _commandRepo = new CommandRepository(ssh);
 }
Пример #6
0
 public Cron(SshCredentials ssh)
 {
     _commandRepo = new CommandRepository(ssh);
 }
Пример #7
0
        //---------------------------------------------------------------------
        // Static members

        /// <summary>
        /// Establishes a SSH connection to the remote Raspberry Pi whose
        /// connection information is passed.
        /// </summary>
        /// <param name="connectionInfo">The connection information.</param>
        /// <param name="usePassword">Optionally forces use of the password instead of the public key.</param>
        /// <param name="projectSettings">
        /// Optionally specifies the project settings.  This must be specified for connections that
        /// will be used for remote debugging but may be omitted for connections just used for setting
        /// things up like SSH keys, etc.
        /// </param>
        /// <returns>The connection.</returns>
        /// <exception cref="Exception">Thrown when the connection could not be established.</exception>
        public static async Task <Connection> ConnectAsync(ConnectionInfo connectionInfo, bool usePassword = false, ProjectSettings projectSettings = null)
        {
            Covenant.Requires <ArgumentNullException>(connectionInfo != null, nameof(connectionInfo));

            try
            {
                if (!NetHelper.TryParseIPv4Address(connectionInfo.Host, out var address))
                {
                    Log($"DNS lookup for: {connectionInfo.Host}");

                    address = (await Dns.GetHostAddressesAsync(connectionInfo.Host)).FirstOrDefault();
                }

                if (address == null)
                {
                    throw new ConnectionException(connectionInfo.Host, "DNS lookup failed.");
                }

                SshCredentials credentials;

                if (string.IsNullOrEmpty(connectionInfo.PrivateKeyPath) || usePassword)
                {
                    Log($"[{connectionInfo.Host}]: Auth via username/password");

                    credentials = SshCredentials.FromUserPassword(connectionInfo.User, connectionInfo.Password);
                }
                else
                {
                    Log($"[{connectionInfo.Host}]: Auth via SSH keys");

                    credentials = SshCredentials.FromPrivateKey(connectionInfo.User, File.ReadAllText(connectionInfo.PrivateKeyPath));
                }

                var connection = new Connection(connectionInfo.Host, address, connectionInfo, credentials, projectSettings);

                connection.Connect(TimeSpan.Zero);
                await connection.InitializeAsync();

                return(connection);
            }
            catch (SshProxyException e)
            {
                if (usePassword ||
                    e.InnerException == null ||
                    e.InnerException.GetType() != typeof(SshAuthenticationException))
                {
                    RaspberryDebugger.Log.Exception(e, $"[{connectionInfo.Host}]");
                    throw;
                }

                if (string.IsNullOrEmpty(connectionInfo.PrivateKeyPath) ||
                    string.IsNullOrEmpty(connectionInfo.Password))
                {
                    RaspberryDebugger.Log.Exception(e, $"[{connectionInfo.Host}]: The connection must have a password or SSH private key.");
                    throw;
                }

                RaspberryDebugger.Log.Warning($"[{connectionInfo.Host}]: SSH auth failed: Try using the password and reauthorizing the public key");

                // SSH private key authentication didn't work.  This commonly happens
                // after the user has reimaged the Raspberry.  It's likely that the
                // user has setup the same username/password, so we'll try logging in
                // with those and just configure the current public key to be accepted
                // on the Raspberry.

                try
                {
                    var connection = await ConnectAsync(connectionInfo, usePassword : true);

                    // Append the public key to the user's [authorized_keys] file if it's
                    // not already present.

                    RaspberryDebugger.Log.Info($"[{connectionInfo.Host}]: Reauthorizing the public key");

                    var homeFolder = LinuxPath.Combine("/", "home", connectionInfo.User);
                    var publicKey  = File.ReadAllText(connectionInfo.PublicKeyPath).Trim();
                    var keyScript  =
                        $@"
mkdir -p {homeFolder}/.ssh
touch {homeFolder}/.ssh/authorized_keys

if ! grep --quiet '{publicKey}' {homeFolder}/.ssh/authorized_keys ; then
    echo '{publicKey}' >> {homeFolder}/.ssh/authorized_keys
    exit $?
fi

exit 0
";
                    connection.ThrowOnError(connection.RunCommand(CommandBundle.FromScript(keyScript)));
                    return(connection);
                }
                catch (Exception e2)
                {
                    // We've done all we can.

                    RaspberryDebugger.Log.Exception(e2, $"[{connectionInfo.Host}]");
                    throw;
                }
            }
            catch (Exception e)
            {
                RaspberryDebugger.Log.Exception(e, $"[{connectionInfo.Host}]");
                throw;
            }
        }
Пример #8
0
        /// <summary>
        /// Constructs a connection using a password.
        /// </summary>
        /// <param name="name">The server name.</param>
        /// <param name="address">The IP address.</param>
        /// <param name="connectionInfo">The connection information.</param>
        /// <param name="credentials">The SSH credentials.</param>
        /// <param name="projectSettings">
        /// Optionally specifies the project settings.  This must be specified for connections that
        /// will be used for remote debugging but may be omitted for connections just used for setting
        /// things up like SSH keys, etc.
        /// </param>
        private Connection(string name, IPAddress address, ConnectionInfo connectionInfo, SshCredentials credentials, ProjectSettings projectSettings)
            : base(name, address, credentials, connectionInfo.Port, logWriter: null)
        {
            this.connectionInfo  = connectionInfo;
            this.projectSettings = projectSettings;

            // Disable connection level logging, etc.

            DefaultRunOptions = RunOptions.None;
        }
Пример #9
0
 public SambaService(SshCredentials ssh)
 {
     _commandRepo    = new CommandRepository(ssh);
     _serviceService = new Service(ssh);
 }
Пример #10
0
 public Samba(SshCredentials ssh)
 {
     _sambaService = new SambaService(ssh);
 }
Пример #11
0
 /// <summary>Attach logger, and execute commands on SSH target</summary>
 /// <param name="logger">Logger for detailed information about failed commands</param>
 /// <param name="ssh">Ssh connection credentials</param>
 public SystemInformation(ILogger logger, SshCredentials ssh)
 {
     _service = new SystemService(logger, ssh);
 }
Пример #12
0
 internal CommandRepository(ILogger logger, SshCredentials ssh)
 {
     _logger = logger; _ssh = ssh;
 }
Пример #13
0
 internal CommandRepository(SshCredentials ssh)
 {
     _ssh = ssh;
 }
Пример #14
0
        /// <summary>
        /// Constructor.  Note that you should dispose the instance when you're finished with it.
        /// </summary>
        /// <param name="addressOrFQDN">The target XenServer IP address or FQDN.</param>
        /// <param name="username">The user name.</param>
        /// <param name="password">The password.</param>
        /// <param name="name">Optionally specifies the XenServer name.</param>
        /// <param name="logFolder">
        /// The folder where log files are to be written, otherwise or <c>null</c> or
        /// empty if logging is disabled.
        /// </param>
        public XenClient(string addressOrFQDN, string username, string password, string name = null, string logFolder = null)
        {
            Covenant.Requires <ArgumentNullException>(!string.IsNullOrEmpty(username));

            if (!IPAddress.TryParse(addressOrFQDN, out var address))
            {
                var hostEntry = Dns.GetHostEntry(addressOrFQDN);

                if (hostEntry.AddressList.Length == 0)
                {
                    throw new XenException($"[{addressOrFQDN}] is not a valid IP address or fully qualified domain name of a XenServer host.");
                }

                address = hostEntry.AddressList.First();
            }

            var logWriter = (TextWriter)null;

            if (!string.IsNullOrEmpty(logFolder))
            {
                Directory.CreateDirectory(logFolder);

                logWriter = new StreamWriter(Path.Combine(logFolder, $"XENSERVER-{addressOrFQDN}.log"));
            }

            Address           = addressOrFQDN;
            Name              = name;
            SshProxy          = new SshProxy <XenClient>(addressOrFQDN, null, address, SshCredentials.FromUserPassword(username, password), logWriter);
            SshProxy.Metadata = this;
            runOptions        = RunOptions.IgnoreRemotePath;

            // Initialize the operation classes.

            Repository = new RepositoryOperations(this);
            Template   = new TemplateOperations(this);
            Machine    = new MachineOperations(this);
        }
Пример #15
0
 public Samba(ILogger logger, SshCredentials ssh)
 {
     _sambaService = new SambaService(logger, ssh);
 }
Пример #16
0
 public Service(ILogger logger, SshCredentials ssh)
 {
     _commandRepo = new CommandRepository(logger, ssh);
 }
Пример #17
0
 /// <summary>Execute commands on SSH target</summary>
 public SystemInformation(SshCredentials ssh)
 {
     _service = new SystemService(ssh);
 }
Пример #18
0
 public TransmissionService(SshCredentials ssh)
 {
     _commandRepo = new CommandRepository(ssh);
 }