Exemplo n.º 1
0
        /// <summary>
        /// A numerical representing a permission matrix. These permissions are overridden on Windows platforms, and are therefore useless on such a host. Default value on UNIX platforms are 644. If left empty, no permissioins will be applied.
        /// </summary>
        /// <param name="permissions"></param>
        /// <param name="filePath"></param>
        public void ApplySecurityPermissions(string permissions, string filePath)
        {
            // Don't apply if empty
            if (String.IsNullOrEmpty(permissions))
            {
                return;
            }

            try
            {
                byte[] buffer = Encoding.Default.GetBytes(permissions);
                int    perm   = 0;
                foreach (byte t in buffer)
                {
                    int currentPos = t;
                    if (currentPos < '0' || currentPos > '7')
                    {
                        perm = -1;
                        break;
                    }

                    perm <<= 3;
                    perm  |= currentPos - '0';
                }

                _sftp.ChangePermissions(filePath, (short)perm);
            }
            catch { throw new Exception("Unable to parse permissions to integer"); }
        }
        private void TransferPrereqs(SshClient sshClient, ServerDistro distro)
        {
            string prereqsPath = (distro == ServerDistro.RPM) ? rpmPackages : debianPackages;

            using (var sftpClient = new SftpClient(sshClient.ConnectionInfo))
            {
                sftpClient.Connect();

                List <string> files = ListPrereqsFiles(prereqsPath);
                foreach (string file in files)
                {
                    using (var fileStream = new FileStream(file, FileMode.Open))
                    {
                        Console.WriteLine("Uploading {0} ({1:N0} bytes)", file, fileStream.Length);
                        sftpClient.BufferSize = 4 * 1024; // bypass Payload error large files
                        string   path     = file.Remove(file.IndexOf(Path.GetFileName(file))).Replace(@"\", "/");
                        string   filename = Path.GetFileName(file);
                        string[] dirs     = path.TrimEnd('/').Split('/');
                        foreach (var dir in dirs)
                        {
                            try
                            {
                                if (!sftpClient.Exists(dir))
                                {
                                    sftpClient.CreateDirectory(dir);
                                }
                                sftpClient.ChangeDirectory(dir);
                            }
                            catch
                            {
                                //Log: Directory already exists
                            }
                        }
                        if (sftpClient.Exists(filename))
                        {
                            sftpClient.UploadFile(fileStream, filename);
                        }
                        sftpClient.ChangePermissions(filename, 755);
                        sftpClient.ChangeDirectory("/home/" + sshClient.ConnectionInfo.Username);
                    }
                }
            }

            ////chmod +x for the file to be executable
            //var cmd = sshClient.CreateCommand("chmod +x ./" + Path.GetFileName(agentPath));
            //var result = cmd.BeginExecute();
            //using (var reader = new StreamReader(cmd.OutputStream, Encoding.UTF8, true, 1024, true))
            //{
            //    while (!result.IsCompleted || !reader.EndOfStream)
            //    {
            //        string line = reader.ReadLine();
            //        if (line != null)
            //        {
            //            //Log: result
            //        }
            //    }
            //}
            //cmd.EndExecute(result);
        }
Exemplo n.º 3
0
        private static bool Upload(ref SftpClient sftp, string FileName, string Source, string TargetDir, short SetPermissions = 0)
        {
            string _stage = "";
            string _file  = TargetDir + FileName;

            try
            {
                //
                _stage = "Checkings";
                if (SetPermissions != 0)
                {
                    if (SetPermissions < 700 || SetPermissions > 777)
                    {
                        throw new Exception($"Wrong permissions: {SetPermissions}");
                    }
                }


                if (!File.Exists(Source))
                {
                    throw new Exception("Source file not found.");
                }
                if (sftp.Exists(_file))
                {
                    throw new Exception("Target file already exists.");
                }

                //
                _stage = "Changing remote directory";
                sftp.ChangeDirectory(TargetDir);

                //
                _stage = "Uploading file";
                using (FileStream fs = new FileStream(Source, FileMode.Open))
                {
                    sftp.BufferSize = 4 * 1024;
                    sftp.UploadFile(fs, Path.GetFileName(Source));
                    if (SetPermissions != 0)
                    {
                        sftp.ChangePermissions(_file, SetPermissions);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"[{_stage}] {ex.Message}");
                return(false);
            }

            // OK
            return(true);
        }
Exemplo n.º 4
0
        public override string GetCommandText(ActConsoleCommand act)
        {
            string cmd = "";

            switch (act.ConsoleCommand)
            {
            case ActConsoleCommand.eConsoleCommand.FreeCommand:
                return(GetParameterizedCommand(act));

            case ActConsoleCommand.eConsoleCommand.ParametrizedCommand:
                return(GetParameterizedCommand(act));

            case ActConsoleCommand.eConsoleCommand.Script:

                VerifyFTPConnected();

                if (!UnixFTPClient.Exists(workdir + @"/Ginger"))
                {
                    UnixFTPClient.CreateDirectory(workdir + @"/Ginger");
                }

                string SHFilesPath        = mScriptsFolder;
                string UnixScriptFilePath = workdir + @"/Ginger/" + act.ScriptName;
                using (var f = File.OpenRead(SHFilesPath + act.ScriptName))
                {
                    UnixFTPClient.UploadFile(f, UnixScriptFilePath, null);
                }

                UnixFTPClient.ChangePermissions(UnixScriptFilePath, 777);
                foreach (var p in act.InputValues)
                {
                    if (!string.IsNullOrEmpty(p.Value))
                    {
                        cmd += " " + p.ValueForDriver;
                    }
                }
                if (UnixScriptFilePath.Trim().EndsWith(".sh", StringComparison.CurrentCultureIgnoreCase))
                {
                    return("dos2unix " + UnixScriptFilePath + ";sh " + UnixScriptFilePath + cmd);
                }
                else
                {
                    return("dos2unix " + UnixScriptFilePath + "; " + UnixScriptFilePath + cmd);
                }

            default:
                Reporter.ToLog(eLogLevel.WARN, "Error - unknown command");
                ErrorMessageFromDriver += "Error - unknown command";
                return("Error - unknown command");
            }
        }
Exemplo n.º 5
0
        public bool Upload(string fileName, string sourceDir, string targetDir, short setPermissions = 0)
        {
            string _stage      = "";
            string _sourceFile = sourceDir + fileName;
            string _targetFile = targetDir + fileName;

            try
            {
                //
                _stage = "Checkings";
                if (setPermissions != 0)
                {
                    if (setPermissions < 700 || setPermissions > 777)
                    {
                        throw new Exception($"Wrong permissions: {setPermissions}");
                    }
                }

                if (!File.Exists(_sourceFile))
                {
                    throw new Exception("Source file not found.");
                }
                if (pSFtp.Exists(_targetFile))
                {
                    throw new Exception("Target file already exists.");
                }

                //
                _stage = "Changing remote directory";
                pSFtp.ChangeDirectory(targetDir);

                //
                _stage = "Uploading file";
                using (FileStream fs = new FileStream(_sourceFile, FileMode.Open))
                {
                    pSFtp.BufferSize = 4 * 1024;
                    pSFtp.UploadFile(fs, Path.GetFileName(_sourceFile));
                    if (setPermissions != 0)
                    {
                        pSFtp.ChangePermissions(_targetFile, setPermissions);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"[Upload#{_stage}] {ex.Message}");
            }

            // OK
            return(true);
        }
Exemplo n.º 6
0
        public bool RemoteChangePermissions(string fileName, short setPermissions)
        {
            string _stage = "";

            //
            _stage = "Changing file permissions";
            try
            {
                pSFtp.ChangePermissions(fileName, setPermissions);
            }
            catch (Exception ex)
            {
                throw new Exception($"[RemoteChangePermissions#{_stage}] {ex.Message}.");
            }
            return(true);
        }
        private void TransferAgents(SshClient sshClient, ServerArchitecture arch)
        {
            string agentPath = (arch == ServerArchitecture.x64) ? x64Agent : x86Agent;

            using (var sftpClient = new SftpClient(sshClient.ConnectionInfo))
            {
                sftpClient.Connect();
                if (sftpClient.Exists(Path.GetFileName(agentPath)))
                {
                    //Log: Agent already exists on destination
                    return;
                }
                using (var fileStream = new FileStream(agentPath, FileMode.Open))
                {
                    string filename = Path.GetFileName(agentPath);
                    Console.WriteLine("Uploading {0} ({1:N0} bytes)", agentPath, fileStream.Length);
                    sftpClient.BufferSize = 4 * 1024; // bypass Payload error large files
                    sftpClient.UploadFile(fileStream, filename);
                    sftpClient.ChangePermissions(filename, 755);
                }
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Sync <paramref name="sourceDir"/> with <paramref name="destDir"/>
        /// </summary>
        /// <param name="connectInfo">Credentials to access host where synchronization takes place.</param>
        /// <param name="sourceDir">Source directory on the local host.</param>
        /// <param name="destDir">Destination directory on the remote host</param>
        /// <param name="logger">Logging facility</param>
        /// <returns><c>true</c> if successful; otherwise, <c>false</c>.</returns>
        private static bool SyncTo(ConnectionInfo connectInfo, UDirectory sourceDir, UDirectory destDir, LoggerResult logger)
        {
            // Copy files over
            using (var sftp = new SftpClient(connectInfo))
            {
                try
                {
                    sftp.Connect();
                    if (!sftp.IsConnected)
                    {
                        return(false);
                    }
                }
                catch
                {
                    logger.Error("Cannot connect");
                    return(false);
                }

                // Perform recursive copy of all the folders under `sourceDir`. This is required
                // as the sftp client only synchronize directories at their level only, no
                // subdirectory.
                var dirs = new Queue <DirectoryInfo>();
                dirs.Enqueue(new DirectoryInfo(sourceDir));
                var parentPath = sourceDir;
                while (dirs.Count != 0)
                {
                    var currentDir  = dirs.Dequeue();
                    var currentPath = new UDirectory(currentDir.FullName);
                    foreach (var subdir in currentDir.EnumerateDirectories())
                    {
                        dirs.Enqueue(subdir);
                    }

                    // Get the destination path by adding to `Location` the relative path of `sourceDir` to `currentDir`.
                    var destination = UPath.Combine(destDir, currentPath.MakeRelative(parentPath));

                    logger.Info("Synchronizing " + currentPath + " with " + destination.FullPath);
                    // Try to create a remote directory. If it throws an exception, we will assume
                    // for now that the directory already exists. See https://github.com/sshnet/SSH.NET/issues/25
                    try
                    {
                        sftp.CreateDirectory(destination.FullPath);
                        logger.Info("Creating remote directory " + destination.FullPath);
                    }
                    catch (SshException)
                    {
                        // Do nothing, as this is when the directory already exists
                    }
                    // Synchronize files.
                    foreach (var file in sftp.SynchronizeDirectories(currentPath.FullPath, destination.FullPath, "*"))
                    {
                        logger.Info("Updating " + file.Name);
                        // Some of our files needs executable rights, however we do not know in advance which one
                        // need it. For now all files will be rwxr.xr.x (0755 in octal but written in decimal for readability).
                        sftp.ChangePermissions(destination.FullPath + "/" + file.Name, 755);
                    }
                }
                return(true);
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Used for temporarily uploading an ISO disk to a XenServer such that it can be mounted
        /// to a VM, typically for one-time initialization purposes.  neonKUBE uses this as a very
        /// simple poor man's alternative to <b>cloud-init</b> for initializing a VM on first boot.
        /// </summary>
        /// <param name="isoPath">Path to the source ISO file on the local workstation.</param>
        /// <param name="srName">Optionally specifies the storage repository name.  <b>neon-UUID</b> with a generated UUID will be used by default.</param>
        /// <returns>A <see cref="XenTempIso"/> with information about the new storage repository and its contents.</returns>
        /// <remarks>
        /// <para>
        /// During cluster setup on virtualization platforms like XenServer and Hyper-V, neonKUBE need
        /// to configure new VMs with IP addresses, hostnames, etc.  Traditionally, we've relied on
        /// being able to SSH into the VM to perform all of these actions, but this relied on being
        /// VM being able to obtain an IP address via DHCP and for setup to be able to discover the
        /// assigned address.
        /// </para>
        /// <para>
        /// The dependency on DHCP is somewhat problematic, because it's conceivable that this may
        /// not be available for more controlled environments.  We looked into using Linux <b>cloud-init</b>
        /// for this, but that requires additional local infrastructure for non-cloud deployments and
        /// was also a bit more complex than what we had time for.
        /// </para>
        /// <para>
        /// Instead of <b>cloud-init</b>, we provisioned our XenServer and Hyper-V node templates
        /// with a <b>neon-init</b> service that runs before the network service to determine
        /// whether a DVD (ISO) is inserted into the VM and runs the <b>neon-init.sh</b> script
        /// there one time, if it exists.  This script will initialize the node's IP address and
        /// could also be used for other configuration as well, like setting user credentials.
        /// </para>
        /// <note>
        /// In theory, we could have used the same technique for mounting a <b>cloud-init</b> data source
        /// via this ISO, but we decided not to go there, at least for now (we couldn't get that working).
        /// </note>
        /// <note>
        /// neonKUBE doesn't use this technique for true cloud deployments (AWS, Azure, Google,...) because
        /// we can configure VM networking directly via the cloud APIs.
        /// </note>
        /// <para>
        /// The XenServer requires the temporary ISO implementation to be a bit odd.  We want these temporary
        /// ISOs to be created directly on the XenServer host machine so users won't have to configure any
        /// additional infrastructure as well as to simplify cluster setup.  We'll be creating a local
        /// ISO storage repository from a folder on the host.  Any files to be added to the repository
        /// must exist when the repository is created and it is not possible to add, modify, or remove
        /// files from a repository after its been created.
        /// </para>
        /// <note>
        /// XenServer hosts have only 4GB of free space at the root Linux level, so you must take care
        /// not to create large ISOs or to allow these to accumulate.
        /// </note>
        /// <para>
        /// This method uploads the ISO file <paramref name="isoPath"/> from the local workstation to
        /// the XenServer host, creating a new folder named with a UUID.  Then a new storage repository
        /// will be created from this folder and a <see cref="XenTempIso"/> will be returned holding
        /// details about the new storage repository and its contents.  The setup code will use this to
        /// insert the ISO into a VM.
        /// </para>
        /// <para>
        /// Once the setup code is done with the ISO, it will eject it from the VM and call
        /// <see cref="RemoveTempIso(XenTempIso)"/> to remove the storage repository.
        /// </para>
        /// </remarks>
        public XenTempIso CreateTempIso(string isoPath, string srName = null)
        {
            Covenant.Requires <ArgumentNullException>(!string.IsNullOrEmpty(isoPath), nameof(isoPath));

            if (string.IsNullOrEmpty(srName))
            {
                srName = "neon-" + Guid.NewGuid().ToString("d");
            }

            var tempIso = new XenTempIso();

            // Create the temporary SR subfolder and upload the ISO file.

            var srMountPath = "/var/run/sr-mount";

            tempIso.SrPath  = LinuxPath.Combine(srMountPath, Guid.NewGuid().ToString("d"));
            tempIso.IsoName = $"neon-dvd-{Guid.NewGuid().ToString("d")}.iso";

            if (!sftpClient.PathExists(srMountPath))
            {
                sftpClient.CreateDirectory(srMountPath);
            }

            if (!sftpClient.PathExists(tempIso.SrPath))
            {
                sftpClient.CreateDirectory(tempIso.SrPath);
                sftpClient.ChangePermissions(tempIso.SrPath, Convert.ToInt16("751", 8));
            }

            var xenIsoPath = LinuxPath.Combine(tempIso.SrPath, tempIso.IsoName);

            using (var isoInput = File.OpenRead(isoPath))
            {
                sftpClient.UploadFile(isoInput, xenIsoPath);
                sftpClient.ChangePermissions(xenIsoPath, Convert.ToInt16("751", 8));
            }

            // Create the new storage repository.  This command returns the [sr-uuid].

            var response = SafeInvoke("sr-create",
                                      $"name-label={tempIso.IsoName}",
                                      $"type=iso",
                                      $"device-config:location={tempIso.SrPath}",
                                      $"device-config:legacy_mode=true",
                                      $"content-type=iso");

            tempIso.SrUuid = response.OutputText.Trim();

            // XenServer created a PBD behind the scenes for the new SR.  We're going
            // to need its UUID so we can completely remove the SR later.  Note that
            // doesn't seem to appear immediately so, we'll retry a few times.

            var retry = new ExponentialRetryPolicy(typeof(InvalidOperationException), maxAttempts: 5, initialRetryInterval: TimeSpan.FromSeconds(0.5), maxRetryInterval: TimeSpan.FromSeconds(5));

            retry.Invoke(
                () =>
            {
                var result = SafeInvokeItems("pbd-list", $"sr-uuid={tempIso.SrUuid}");

                tempIso.PdbUuid = result.Items.Single()["uuid"];

                // Obtain the UUID for the ISO's VDI within the SR.

                result = SafeInvokeItems("vdi-list", $"sr-uuid={tempIso.SrUuid}");

                tempIso.VdiUuid = result.Items.Single()["uuid"];
            });

            return(tempIso);
        }
Exemplo n.º 10
0
 public void ChangePermissionsTest()
 {
     ConnectionInfo connectionInfo = null; // TODO: Initialize to an appropriate value
     SftpClient target = new SftpClient(connectionInfo); // TODO: Initialize to an appropriate value
     string path = string.Empty; // TODO: Initialize to an appropriate value
     short mode = 0; // TODO: Initialize to an appropriate value
     target.ChangePermissions(path, mode);
     Assert.Inconclusive("A method that does not return a value cannot be verified.");
 }