From 4b669a0d49b87b94f26cf763e8ff423d6263dc2a Mon Sep 17 00:00:00 2001 From: kota kanbe Date: Fri, 29 Jul 2016 14:30:40 +0900 Subject: [PATCH] Fix no tty error while executing with -external-ssh option --- README.ja.md | 6 +++++- README.md | 5 +++++ scan/redhat.go | 50 ++++++++++--------------------------------------- scan/sshutil.go | 8 +++++++- 4 files changed, 27 insertions(+), 42 deletions(-) diff --git a/README.ja.md b/README.ja.md index 9c22264d..fdae0cf4 100644 --- a/README.ja.md +++ b/README.ja.md @@ -669,7 +669,11 @@ Vulsは2種類のSSH接続方法をサポートしている。 これは、SSHコマンドがインストールされていない環境でも動作する(Windowsなど) 外部SSHコマンドを使ってスキャンするためには、`-ssh-external`を指定する。 -SSH Configが使えるので、ProxyCommandを使った多段SSHなどが可能。 +SSH Configが使えるので、ProxyCommandを使った多段SSHなどが可能。 +CentOSでは、スキャン対象サーバの/etc/sudoersに以下を追加する必要がある(user: vuls) +``` +Defaults:vuls !requiretty +``` ## -ask-key-password option diff --git a/README.md b/README.md index 267e1c7e..0eda8641 100644 --- a/README.md +++ b/README.md @@ -669,6 +669,11 @@ This is useful in situations where you may not have access to traditional UNIX t To use external ssh command, specify this option. This is useful If you want to use ProxyCommand or chiper algorithm of SSH that is not supported by native go implementation. +Don't forget to add below line to /etc/sudoers on the target servers. (username: vuls) +``` +Defaults:vuls !requiretty +``` + ## -ask-key-password option diff --git a/scan/redhat.go b/scan/redhat.go index d202850d..ac1ee9ac 100644 --- a/scan/redhat.go +++ b/scan/redhat.go @@ -303,30 +303,19 @@ func (o *redhat) scanUnsecurePackagesUsingYumCheckUpdate() (CvePacksList, error) // { packageName: changelog-lines } var rpm2changelog map[string]*string - if !config.Conf.SSHExternal { - allChangelog, err := o.getAllChangelog(packInfoList) - if err != nil { - o.log.Errorf("Failed to getAllchangelog. err: %s", err) - return nil, err - } - rpm2changelog, err = o.parseAllChangelog(allChangelog) - if err != nil { - return nil, fmt.Errorf("Failed to parseAllChangelog. err: %s", err) - } + allChangelog, err := o.getAllChangelog(packInfoList) + if err != nil { + o.log.Errorf("Failed to getAllchangelog. err: %s", err) + return nil, err + } + rpm2changelog, err = o.parseAllChangelog(allChangelog) + if err != nil { + return nil, fmt.Errorf("Failed to parseAllChangelog. err: %s", err) } var results []PackInfoCveIDs for i, packInfo := range packInfoList { - changelog := "" - if !config.Conf.SSHExternal { - changelog = o.getChangelogCVELines(rpm2changelog, packInfo) - } else { - changelog, err = o.getChangelog(packInfo.Name) - if err != nil { - o.log.Errorf("Failed to collect CVE IDs. err: %s", err) - return nil, err - } - } + changelog := o.getChangelogCVELines(rpm2changelog, packInfo) // Collect unique set of CVE-ID in each changelog uniqueCveIDMap := make(map[string]bool) @@ -470,25 +459,6 @@ func (o *redhat) parseYumCheckUpdateLine(line string) (models.PackageInfo, error }, nil } -func (o *redhat) getChangelog(packageNames string) (stdout string, err error) { - command := "" - if o.ServerInfo.User == "root" { - command = "echo N | " - } - if 0 < len(config.Conf.HTTPProxy) { - command += util.ProxyEnv() - } - - // yum update --changelog doesn't have --color option. - command += fmt.Sprintf(" yum update --changelog %s | grep CVE", packageNames) - - r := o.ssh(command, sudo) - if !r.isSuccess(0, 1) { - return "", fmt.Errorf("Failed to SSH: %s", r) - } - return r.Stdout, nil -} - func (o *redhat) mkPstring() *string { str := "" return &str @@ -609,7 +579,7 @@ func (o *redhat) getAllChangelog(packInfoList models.PackageInfoList) (stdout st } // yum update --changelog doesn't have --color option. - command += fmt.Sprintf(" yum update --changelog %s", packageNames) + command += fmt.Sprintf(" LANG=en_US.UTF-8 yum update --changelog %s", packageNames) r := o.ssh(command, sudo) if !r.isSuccess(0, 1) { diff --git a/scan/sshutil.go b/scan/sshutil.go index 1c30e5ed..e4397d8a 100644 --- a/scan/sshutil.go +++ b/scan/sshutil.go @@ -126,7 +126,7 @@ func parallelSSHExec(fn func(osTypeInterface) error, timeoutSec ...int) (errs [] } func sshExec(c conf.ServerInfo, cmd string, sudo bool, log ...*logrus.Entry) (result sshResult) { - if runtime.GOOS == "windows" || !conf.Conf.SSHExternal { + if isSSHExecNative() { result = sshExecNative(c, cmd, sudo) } else { result = sshExecExternal(c, cmd, sudo) @@ -137,6 +137,10 @@ func sshExec(c conf.ServerInfo, cmd string, sudo bool, log ...*logrus.Entry) (re return } +func isSSHExecNative() bool { + return runtime.GOOS == "windows" || !conf.Conf.SSHExternal +} + func sshExecNative(c conf.ServerInfo, cmd string, sudo bool) (result sshResult) { result.Servername = c.ServerName result.Host = c.Host @@ -203,6 +207,7 @@ func sshExecExternal(c conf.ServerInfo, cmd string, sudo bool) (result sshResult } defaultSSHArgs := []string{ + "-t", "-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null", "-o", "LogLevel=quiet", @@ -289,6 +294,7 @@ func decolateCmd(c conf.ServerInfo, cmd string, sudo bool) string { cmd = fmt.Sprintf(`docker exec %s /bin/bash -c "%s"`, c.Container.ContainerID, cmd) } } + // cmd = fmt.Sprintf("set -x; %s", cmd) return cmd }