Skip to content

Commit

Permalink
ssh: Introduce ssh.CopyDataPrivileged
Browse files Browse the repository at this point in the history
Currently it's only possible to copy data to a file in the VM as root,
it's not possible to do this as the 'core' user. This was not needed so
far, but the next commit will have a need for this.
This commit adds a CopyDataPrivileged/CopyData similar to
RunPrivileged/Run
  • Loading branch information
cfergeau authored and praveenkumar committed Jun 16, 2022
1 parent 4425817 commit d8c2d89
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 16 deletions.
4 changes: 2 additions & 2 deletions pkg/crc/cluster/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ func addProxyCACertToCluster(sshRunner *ssh.Runner, ocConfig oc.Config, proxy *n
// Replace the carriage return ("\n" or "\r\n") with literal `\n` string
re := regexp.MustCompile(`\r?\n`)
p := fmt.Sprintf(proxyCABundleTemplate, re.ReplaceAllString(proxy.ProxyCACert, `\n`), trustedCAName)
err := sshRunner.CopyData([]byte(p), proxyConfigMapFileName, 0644)
err := sshRunner.CopyDataPrivileged([]byte(p), proxyConfigMapFileName, 0644)
if err != nil {
return err
}
Expand Down Expand Up @@ -378,7 +378,7 @@ func EnsurePullSecretPresentOnInstanceDisk(sshRunner *ssh.Runner, pullSecret Pul
if err != nil {
return err
}
return sshRunner.CopyData([]byte(content), vmPullSecretPath, 0600)
return sshRunner.CopyDataPrivileged([]byte(content), vmPullSecretPath, 0600)
}

func WaitForPullSecretPresentOnInstanceDisk(ctx context.Context, sshRunner *ssh.Runner) error {
Expand Down
10 changes: 5 additions & 5 deletions pkg/crc/machine/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,7 @@ func updateSSHKeyPair(sshRunner *crcssh.Runner) error {
logging.Info("Updating authorized keys...")
// CopyData uses sudo and we need to use it
// because of https://bugzilla.redhat.com/show_bug.cgi?id=1956739
err = sshRunner.CopyData(publicKey, "/home/core/.ssh/authorized_keys", 0644)
err = sshRunner.CopyDataPrivileged(publicKey, "/home/core/.ssh/authorized_keys", 0644)
if err != nil {
return err
}
Expand Down Expand Up @@ -669,7 +669,7 @@ func configurePodmanProxy(ctx context.Context, sshRunner *crcssh.Runner, proxy *
proxyEnv.WriteString(fmt.Sprintf("no_proxy=%s\n", proxy.GetNoProxyString()))
proxyEnv.WriteString(fmt.Sprintf("NO_PROXY=%s\n", proxy.GetNoProxyString()))
}
err = sshRunner.CopyData([]byte(proxyEnv.String()), "/etc/environment.d/proxy-env.conf", 0644)
err = sshRunner.CopyDataPrivileged([]byte(proxyEnv.String()), "/etc/environment.d/proxy-env.conf", 0644)
if err != nil {
return err
}
Expand All @@ -679,7 +679,7 @@ func configurePodmanProxy(ctx context.Context, sshRunner *crcssh.Runner, proxy *
return err
}
podmanServiceConf := "[Service]\nEnvironmentFile=/etc/environment.d/proxy-env.conf\n"
err = sshRunner.CopyData([]byte(podmanServiceConf), "/etc/systemd/system/podman.service.d/proxy-env.conf", 0644)
err = sshRunner.CopyDataPrivileged([]byte(podmanServiceConf), "/etc/systemd/system/podman.service.d/proxy-env.conf", 0644)
if err != nil {
return err
}
Expand Down Expand Up @@ -763,7 +763,7 @@ func ensureRoutesControllerIsRunning(sshRunner *crcssh.Runner, ocConfig oc.Confi
if err != nil {
return err
}
if err := sshRunner.CopyData(bin, "/tmp/routes-controller.json", 0444); err != nil {
if err := sshRunner.CopyDataPrivileged(bin, "/tmp/routes-controller.json", 0444); err != nil {
return err
}
_, _, err = ocConfig.RunOcCommand("apply", "-f", "/tmp/routes-controller.json")
Expand Down Expand Up @@ -811,7 +811,7 @@ func updateCockpitConsoleBearerToken(sshRunner *crcssh.Runner) error {
return fmt.Errorf("failed to write cockpit bearer token: %w", err)
}

if err := sshRunner.CopyData([]byte(token), "/home/core/cockpit-bearer-token", 0600); err != nil {
if err := sshRunner.CopyDataPrivileged([]byte(token), "/home/core/cockpit-bearer-token", 0600); err != nil {
return fmt.Errorf("failed to set token for cockpit: %w", err)
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/crc/network/nameservers.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func GetResolvValuesFromInstance(sshRunner *ssh.Runner) (*ResolvFileValues, erro
func CreateResolvFileOnInstance(sshRunner *ssh.Runner, resolvFileValues ResolvFileValues) error {
resolvFile, _ := CreateResolvFile(resolvFileValues)

err := sshRunner.CopyData([]byte(resolvFile), "/etc/resolv.conf", 0644)
err := sshRunner.CopyDataPrivileged([]byte(resolvFile), "/etc/resolv.conf", 0644)
if err != nil {
return fmt.Errorf("Error creating /etc/resolv on instance: %s", err.Error())
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/crc/services/dns/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func createDnsmasqDNSConfig(serviceConfig services.ServicePostStartConfig) error
return err
}

return serviceConfig.SSHRunner.CopyData([]byte(dnsConfig), "/var/srv/dnsmasq.conf", 0644)
return serviceConfig.SSHRunner.CopyDataPrivileged([]byte(dnsConfig), "/var/srv/dnsmasq.conf", 0644)
}

func createDNSConfigFile(values dnsmasqConfFileValues, tmpl string) (string, error) {
Expand Down
18 changes: 15 additions & 3 deletions pkg/crc/ssh/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,21 +52,33 @@ func (runner *Runner) RunPrivileged(reason string, cmdAndArgs ...string) (string
return runner.runSSHCommand(commandline, false)
}

func (runner *Runner) CopyData(data []byte, destFilename string, mode os.FileMode) error {
func (runner *Runner) copyDataFull(data []byte, destFilename string, mode os.FileMode, privileged bool) error {
var sudo string
if privileged {
sudo = "sudo "
}
logging.Debugf("Creating %s with permissions 0%o in the CRC VM", destFilename, mode)
base64Data := base64.StdEncoding.EncodeToString(data)
command := fmt.Sprintf("sudo install -m 0%o /dev/null %s && cat <<EOF | base64 --decode | sudo tee %s\n%s\nEOF", mode, destFilename, destFilename, base64Data)
command := fmt.Sprintf("%sinstall -m 0%o /dev/null %s && cat <<EOF | base64 --decode | %stee %s\n%s\nEOF", sudo, mode, destFilename, sudo, destFilename, base64Data)
_, _, err := runner.RunPrivate(command)

return err
}

func (runner *Runner) CopyDataPrivileged(data []byte, destFilename string, mode os.FileMode) error {
return runner.copyDataFull(data, destFilename, mode, true)
}

func (runner *Runner) CopyData(data []byte, destFilename string, mode os.FileMode) error {
return runner.copyDataFull(data, destFilename, mode, false)
}

func (runner *Runner) CopyFile(srcFilename string, destFilename string, mode os.FileMode) error {
data, err := ioutil.ReadFile(srcFilename)
if err != nil {
return err
}
return runner.CopyData(data, destFilename, mode)
return runner.CopyDataPrivileged(data, destFilename, mode)
}

func (runner *Runner) runSSHCommand(command string, runPrivate bool) (string, string, error) {
Expand Down
12 changes: 8 additions & 4 deletions pkg/crc/ssh/ssh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,13 @@ func TestRunner(t *testing.T) {
assert.Equal(t, "hello", bin)
cancel()
// Expect error when sending data over close ssh server channel
assert.Error(t, runner.CopyData([]byte(`hello world`), "/hello", 0644))
assert.Error(t, runner.CopyDataPrivileged([]byte(`hello world`), "/hello", 0644))

_, runner, totalConn := createListnerAndSSHServer(t, clientKey, clientKeyFile)
assert.NoError(t, runner.CopyData([]byte(`hello world`), "/hello", 0644))
assert.NoError(t, runner.CopyData([]byte(`hello world`), "/hello", 0644))
assert.NoError(t, runner.CopyData([]byte(`hello world`), "/hello", 0644))
assert.NoError(t, runner.CopyDataPrivileged([]byte(`hello world`), "/hello", 0644))
assert.NoError(t, runner.CopyDataPrivileged([]byte(`hello world`), "/hello", 0644))
assert.NoError(t, runner.CopyDataPrivileged([]byte(`hello world`), "/hello", 0644))
assert.NoError(t, runner.CopyData([]byte(`hello world`), "/home/core/hello", 0644))
assert.Equal(t, 1, *totalConn)
}

Expand All @@ -69,6 +70,9 @@ func createListnerAndSSHServer(t *testing.T, clientKey *ecdsa.PrivateKey, client
if escaped == `"sudo install -m 0644 /dev/null /hello && cat <<EOF | base64 --decode | sudo tee /hello\naGVsbG8gd29ybGQ=\nEOF"` {
return 0, ""
}
if escaped == `"install -m 0644 /dev/null /home/core/hello && cat <<EOF | base64 --decode | tee /home/core/hello\naGVsbG8gd29ybGQ=\nEOF"` {
return 0, ""
}
return 1, fmt.Sprintf("unexpected command: %q", input)
})
return cancel, runner, totalConn
Expand Down

0 comments on commit d8c2d89

Please sign in to comment.