Add local scan mode.
If the scan target server is localhost, Don't use SSH. #210
This commit is contained in:
18
scan/base.go
18
scan/base.go
@@ -41,8 +41,8 @@ type base struct {
|
||||
errs []error
|
||||
}
|
||||
|
||||
func (l *base) ssh(cmd string, sudo bool) sshResult {
|
||||
return sshExec(l.ServerInfo, cmd, sudo, l.log)
|
||||
func (l *base) exec(cmd string, sudo bool) execResult {
|
||||
return exec(l.ServerInfo, cmd, sudo, l.log)
|
||||
}
|
||||
|
||||
func (l *base) setServerInfo(c config.ServerInfo) {
|
||||
@@ -143,7 +143,7 @@ func (l *base) exitedContainers() (containers []config.Container, err error) {
|
||||
|
||||
func (l *base) dockerPs(option string) (string, error) {
|
||||
cmd := fmt.Sprintf("docker ps %s", option)
|
||||
r := l.ssh(cmd, noSudo)
|
||||
r := l.exec(cmd, noSudo)
|
||||
if !r.isSuccess() {
|
||||
return "", fmt.Errorf("Failed to SSH: %s", r)
|
||||
}
|
||||
@@ -152,7 +152,7 @@ func (l *base) dockerPs(option string) (string, error) {
|
||||
|
||||
func (l *base) lxdPs(option string) (string, error) {
|
||||
cmd := fmt.Sprintf("lxc list %s", option)
|
||||
r := l.ssh(cmd, noSudo)
|
||||
r := l.exec(cmd, noSudo)
|
||||
if !r.isSuccess() {
|
||||
return "", fmt.Errorf("failed to SSH: %s", r)
|
||||
}
|
||||
@@ -180,7 +180,7 @@ func (l *base) parseDockerPs(stdout string) (containers []config.Container, err
|
||||
func (l *base) parseLxdPs(stdout string) (containers []config.Container, err error) {
|
||||
lines := strings.Split(stdout, "\n")
|
||||
for i, line := range lines[3:] {
|
||||
if i % 2 == 1 {
|
||||
if i%2 == 1 {
|
||||
continue
|
||||
}
|
||||
fields := strings.Fields(strings.Replace(line, "|", " ", -1))
|
||||
@@ -219,9 +219,9 @@ func (l *base) detectPlatform() error {
|
||||
}
|
||||
|
||||
func (l base) detectRunningOnAws() (ok bool, instanceID string, err error) {
|
||||
if r := l.ssh("type curl", noSudo); r.isSuccess() {
|
||||
if r := l.exec("type curl", noSudo); r.isSuccess() {
|
||||
cmd := "curl --max-time 1 --retry 3 --noproxy 169.254.169.254 http://169.254.169.254/latest/meta-data/instance-id"
|
||||
r := l.ssh(cmd, noSudo)
|
||||
r := l.exec(cmd, noSudo)
|
||||
if r.isSuccess() {
|
||||
id := strings.TrimSpace(r.Stdout)
|
||||
if !l.isAwsInstanceID(id) {
|
||||
@@ -239,9 +239,9 @@ func (l base) detectRunningOnAws() (ok bool, instanceID string, err error) {
|
||||
}
|
||||
}
|
||||
|
||||
if r := l.ssh("type wget", noSudo); r.isSuccess() {
|
||||
if r := l.exec("type wget", noSudo); r.isSuccess() {
|
||||
cmd := "wget --tries=3 --timeout=1 --no-proxy -q -O - http://169.254.169.254/latest/meta-data/instance-id"
|
||||
r := l.ssh(cmd, noSudo)
|
||||
r := l.exec(cmd, noSudo)
|
||||
if r.isSuccess() {
|
||||
id := strings.TrimSpace(r.Stdout)
|
||||
if !l.isAwsInstanceID(id) {
|
||||
|
||||
@@ -48,9 +48,9 @@ func newDebian(c config.ServerInfo) *debian {
|
||||
func detectDebian(c config.ServerInfo) (itsMe bool, deb osTypeInterface, err error) {
|
||||
deb = newDebian(c)
|
||||
|
||||
if r := sshExec(c, "ls /etc/debian_version", noSudo); !r.isSuccess() {
|
||||
if r := exec(c, "ls /etc/debian_version", noSudo); !r.isSuccess() {
|
||||
if r.Error != nil {
|
||||
return false, deb, r.Error
|
||||
return false, deb, nil
|
||||
}
|
||||
if r.ExitStatus == 255 {
|
||||
return false, deb, fmt.Errorf(
|
||||
@@ -60,7 +60,7 @@ func detectDebian(c config.ServerInfo) (itsMe bool, deb osTypeInterface, err err
|
||||
return false, deb, nil
|
||||
}
|
||||
|
||||
if r := sshExec(c, "lsb_release -ir", noSudo); r.isSuccess() {
|
||||
if r := exec(c, "lsb_release -ir", noSudo); r.isSuccess() {
|
||||
// e.g.
|
||||
// root@fa3ec524be43:/# lsb_release -ir
|
||||
// Distributor ID: Ubuntu
|
||||
@@ -79,7 +79,7 @@ func detectDebian(c config.ServerInfo) (itsMe bool, deb osTypeInterface, err err
|
||||
return true, deb, nil
|
||||
}
|
||||
|
||||
if r := sshExec(c, "cat /etc/lsb-release", noSudo); r.isSuccess() {
|
||||
if r := exec(c, "cat /etc/lsb-release", noSudo); r.isSuccess() {
|
||||
// e.g.
|
||||
// DISTRIB_ID=Ubuntu
|
||||
// DISTRIB_RELEASE=14.04
|
||||
@@ -100,7 +100,7 @@ func detectDebian(c config.ServerInfo) (itsMe bool, deb osTypeInterface, err err
|
||||
|
||||
// Debian
|
||||
cmd := "cat /etc/debian_version"
|
||||
if r := sshExec(c, cmd, noSudo); r.isSuccess() {
|
||||
if r := exec(c, cmd, noSudo); r.isSuccess() {
|
||||
deb.setDistro("debian", trim(r.Stdout))
|
||||
return true, deb, nil
|
||||
}
|
||||
@@ -114,7 +114,7 @@ func trim(str string) string {
|
||||
}
|
||||
|
||||
func (o *debian) checkIfSudoNoPasswd() error {
|
||||
r := o.ssh("apt-get -v", sudo)
|
||||
r := o.exec("apt-get -v", sudo)
|
||||
if !r.isSuccess() {
|
||||
o.log.Errorf("sudo error on %s", r)
|
||||
return fmt.Errorf("Failed to sudo: %s", r)
|
||||
@@ -133,7 +133,7 @@ func (o *debian) checkDependencies() error {
|
||||
// Because unable to get changelogs via apt-get changelog on Debian.
|
||||
name := "aptitude"
|
||||
cmd := name + " -h"
|
||||
if r := o.ssh(cmd, noSudo); !r.isSuccess() {
|
||||
if r := o.exec(cmd, noSudo); !r.isSuccess() {
|
||||
o.lackDependencies = []string{name}
|
||||
}
|
||||
return nil
|
||||
@@ -151,7 +151,7 @@ func (o *debian) install() error {
|
||||
// apt-get update
|
||||
o.log.Infof("apt-get update...")
|
||||
cmd := util.PrependProxyEnv("apt-get update")
|
||||
if r := o.ssh(cmd, sudo); !r.isSuccess() {
|
||||
if r := o.exec(cmd, sudo); !r.isSuccess() {
|
||||
msg := fmt.Sprintf("Failed to SSH: %s", r)
|
||||
o.log.Errorf(msg)
|
||||
return fmt.Errorf(msg)
|
||||
@@ -159,7 +159,7 @@ func (o *debian) install() error {
|
||||
|
||||
for _, name := range o.lackDependencies {
|
||||
cmd = util.PrependProxyEnv("apt-get install -y " + name)
|
||||
if r := o.ssh(cmd, sudo); !r.isSuccess() {
|
||||
if r := o.exec(cmd, sudo); !r.isSuccess() {
|
||||
msg := fmt.Sprintf("Failed to SSH: %s", r)
|
||||
o.log.Errorf(msg)
|
||||
return fmt.Errorf(msg)
|
||||
@@ -188,7 +188,7 @@ func (o *debian) scanPackages() error {
|
||||
}
|
||||
|
||||
func (o *debian) scanInstalledPackages() (packs []models.PackageInfo, err error) {
|
||||
r := o.ssh("dpkg-query -W", noSudo)
|
||||
r := o.exec("dpkg-query -W", noSudo)
|
||||
if !r.isSuccess() {
|
||||
return packs, fmt.Errorf("Failed to SSH: %s", r)
|
||||
}
|
||||
@@ -232,7 +232,7 @@ func (o *debian) parseScannedPackagesLine(line string) (name, version string, er
|
||||
|
||||
func (o *debian) checkRequiredPackagesInstalled() error {
|
||||
if o.Distro.Family == "debian" {
|
||||
if r := o.ssh("test -f /usr/bin/aptitude", noSudo); !r.isSuccess() {
|
||||
if r := o.exec("test -f /usr/bin/aptitude", noSudo); !r.isSuccess() {
|
||||
msg := fmt.Sprintf("aptitude is not installed: %s", r)
|
||||
o.log.Errorf(msg)
|
||||
return fmt.Errorf(msg)
|
||||
@@ -244,7 +244,7 @@ func (o *debian) checkRequiredPackagesInstalled() error {
|
||||
func (o *debian) scanUnsecurePackages(installed []models.PackageInfo) ([]models.VulnInfo, error) {
|
||||
o.log.Infof("apt-get update...")
|
||||
cmd := util.PrependProxyEnv("apt-get update")
|
||||
if r := o.ssh(cmd, sudo); !r.isSuccess() {
|
||||
if r := o.exec(cmd, sudo); !r.isSuccess() {
|
||||
return nil, fmt.Errorf("Failed to SSH: %s", r)
|
||||
}
|
||||
|
||||
@@ -328,7 +328,7 @@ func (o *debian) fillCandidateVersion(before models.PackageInfoList) (filled []m
|
||||
names = append(names, p.Name)
|
||||
}
|
||||
cmd := fmt.Sprintf("LANGUAGE=en_US.UTF-8 apt-cache policy %s", strings.Join(names, " "))
|
||||
r := o.ssh(cmd, sudo)
|
||||
r := o.exec(cmd, sudo)
|
||||
if !r.isSuccess() {
|
||||
return nil, fmt.Errorf("Failed to SSH: %s", r)
|
||||
}
|
||||
@@ -350,7 +350,7 @@ func (o *debian) fillCandidateVersion(before models.PackageInfoList) (filled []m
|
||||
|
||||
func (o *debian) GetUpgradablePackNames() (packNames []string, err error) {
|
||||
cmd := util.PrependProxyEnv("LANGUAGE=en_US.UTF-8 apt-get upgrade --dry-run")
|
||||
r := o.ssh(cmd, sudo)
|
||||
r := o.exec(cmd, sudo)
|
||||
if r.isSuccess(0, 1) {
|
||||
return o.parseAptGetUpgrade(r.Stdout)
|
||||
}
|
||||
@@ -529,7 +529,7 @@ func (o *debian) scanPackageCveIDs(pack models.PackageInfo) ([]string, error) {
|
||||
}
|
||||
cmd = util.PrependProxyEnv(cmd)
|
||||
|
||||
r := o.ssh(cmd, noSudo)
|
||||
r := o.exec(cmd, noSudo)
|
||||
if !r.isSuccess() {
|
||||
o.log.Warnf("Failed to SSH: %s", r)
|
||||
// Ignore this Error.
|
||||
@@ -603,8 +603,7 @@ func (o *debian) parseChangelog(changelog string,
|
||||
}
|
||||
|
||||
func (o *debian) splitAptCachePolicy(stdout string) map[string]string {
|
||||
// re := regexp.MustCompile(`(?m:^[^ \t]+:$)`)
|
||||
re := regexp.MustCompile(`(?m:^[^ \t]+:\r\n)`)
|
||||
re := regexp.MustCompile(`(?m:^[^ \t]+:\r?\n)`)
|
||||
ii := re.FindAllStringIndex(stdout, -1)
|
||||
ri := []int{}
|
||||
for i := len(ii) - 1; 0 <= i; i-- {
|
||||
|
||||
@@ -46,9 +46,9 @@ func detectFreebsd(c config.ServerInfo) (itsMe bool, bsd osTypeInterface) {
|
||||
// Prevent from adding `set -o pipefail` option
|
||||
c.Distro = config.Distro{Family: "FreeBSD"}
|
||||
|
||||
if r := sshExec(c, "uname", noSudo); r.isSuccess() {
|
||||
if r := exec(c, "uname", noSudo); r.isSuccess() {
|
||||
if strings.Contains(r.Stdout, "FreeBSD") == true {
|
||||
if b := sshExec(c, "uname -r", noSudo); b.isSuccess() {
|
||||
if b := exec(c, "uname -r", noSudo); b.isSuccess() {
|
||||
rel := strings.TrimSpace(b.Stdout)
|
||||
bsd.setDistro("FreeBSD", rel)
|
||||
return true, bsd
|
||||
@@ -97,7 +97,7 @@ func (o *bsd) scanPackages() error {
|
||||
|
||||
func (o *bsd) scanInstalledPackages() ([]models.PackageInfo, error) {
|
||||
cmd := util.PrependProxyEnv("pkg version -v")
|
||||
r := o.ssh(cmd, noSudo)
|
||||
r := o.exec(cmd, noSudo)
|
||||
if !r.isSuccess() {
|
||||
return nil, fmt.Errorf("Failed to SSH: %s", r)
|
||||
}
|
||||
@@ -107,13 +107,13 @@ func (o *bsd) scanInstalledPackages() ([]models.PackageInfo, error) {
|
||||
func (o *bsd) scanUnsecurePackages() (vulnInfos []models.VulnInfo, err error) {
|
||||
const vulndbPath = "/tmp/vuln.db"
|
||||
cmd := "rm -f " + vulndbPath
|
||||
r := o.ssh(cmd, noSudo)
|
||||
r := o.exec(cmd, noSudo)
|
||||
if !r.isSuccess(0) {
|
||||
return nil, fmt.Errorf("Failed to SSH: %s", r)
|
||||
}
|
||||
|
||||
cmd = util.PrependProxyEnv("pkg audit -F -r -f " + vulndbPath)
|
||||
r = o.ssh(cmd, noSudo)
|
||||
r = o.exec(cmd, noSudo)
|
||||
if !r.isSuccess(0, 1) {
|
||||
return nil, fmt.Errorf("Failed to SSH: %s", r)
|
||||
}
|
||||
|
||||
@@ -48,18 +48,18 @@ func newRedhat(c config.ServerInfo) *redhat {
|
||||
func detectRedhat(c config.ServerInfo) (itsMe bool, red osTypeInterface) {
|
||||
red = newRedhat(c)
|
||||
|
||||
if r := sshExec(c, "ls /etc/fedora-release", noSudo); r.isSuccess() {
|
||||
if r := exec(c, "ls /etc/fedora-release", noSudo); r.isSuccess() {
|
||||
red.setDistro("fedora", "unknown")
|
||||
Log.Warn("Fedora not tested yet: %s", r)
|
||||
return true, red
|
||||
}
|
||||
|
||||
if r := sshExec(c, "ls /etc/redhat-release", noSudo); r.isSuccess() {
|
||||
if r := exec(c, "ls /etc/redhat-release", noSudo); r.isSuccess() {
|
||||
// https://www.rackaid.com/blog/how-to-determine-centos-or-red-hat-version/
|
||||
// e.g.
|
||||
// $ cat /etc/redhat-release
|
||||
// CentOS release 6.5 (Final)
|
||||
if r := sshExec(c, "cat /etc/redhat-release", noSudo); r.isSuccess() {
|
||||
if r := exec(c, "cat /etc/redhat-release", noSudo); r.isSuccess() {
|
||||
re := regexp.MustCompile(`(.*) release (\d[\d.]*)`)
|
||||
result := re.FindStringSubmatch(strings.TrimSpace(r.Stdout))
|
||||
if len(result) != 3 {
|
||||
@@ -79,10 +79,10 @@ func detectRedhat(c config.ServerInfo) (itsMe bool, red osTypeInterface) {
|
||||
return true, red
|
||||
}
|
||||
|
||||
if r := sshExec(c, "ls /etc/system-release", noSudo); r.isSuccess() {
|
||||
if r := exec(c, "ls /etc/system-release", noSudo); r.isSuccess() {
|
||||
family := "amazon"
|
||||
release := "unknown"
|
||||
if r := sshExec(c, "cat /etc/system-release", noSudo); r.isSuccess() {
|
||||
if r := exec(c, "cat /etc/system-release", noSudo); r.isSuccess() {
|
||||
fields := strings.Fields(r.Stdout)
|
||||
if len(fields) == 5 {
|
||||
release = fields[4]
|
||||
@@ -97,7 +97,7 @@ func detectRedhat(c config.ServerInfo) (itsMe bool, red osTypeInterface) {
|
||||
}
|
||||
|
||||
func (o *redhat) checkIfSudoNoPasswd() error {
|
||||
r := o.ssh("yum --version", o.sudo())
|
||||
r := o.exec("yum --version", o.sudo())
|
||||
if !r.isSuccess() {
|
||||
o.log.Errorf("sudo error on %s", r)
|
||||
return fmt.Errorf("Failed to sudo: %s", r)
|
||||
@@ -128,7 +128,7 @@ func (o *redhat) checkDependencies() error {
|
||||
}
|
||||
|
||||
cmd := "rpm -q " + name
|
||||
if r := o.ssh(cmd, noSudo); r.isSuccess() {
|
||||
if r := o.exec(cmd, noSudo); r.isSuccess() {
|
||||
return nil
|
||||
}
|
||||
o.lackDependencies = []string{name}
|
||||
@@ -142,7 +142,7 @@ func (o *redhat) checkDependencies() error {
|
||||
func (o *redhat) install() error {
|
||||
for _, name := range o.lackDependencies {
|
||||
cmd := util.PrependProxyEnv("yum install -y " + name)
|
||||
if r := o.ssh(cmd, sudo); !r.isSuccess() {
|
||||
if r := o.exec(cmd, sudo); !r.isSuccess() {
|
||||
return fmt.Errorf("Failed to SSH: %s", r)
|
||||
}
|
||||
o.log.Infof("Installed: %s", name)
|
||||
@@ -165,7 +165,7 @@ func (o *redhat) checkRequiredPackagesInstalled() error {
|
||||
}
|
||||
|
||||
cmd := "rpm -q " + packName
|
||||
if r := o.ssh(cmd, noSudo); !r.isSuccess() {
|
||||
if r := o.exec(cmd, noSudo); !r.isSuccess() {
|
||||
msg := fmt.Sprintf("%s is not installed", packName)
|
||||
o.log.Errorf(msg)
|
||||
return fmt.Errorf(msg)
|
||||
@@ -194,7 +194,7 @@ func (o *redhat) scanPackages() error {
|
||||
|
||||
func (o *redhat) scanInstalledPackages() (installedPackages models.PackageInfoList, err error) {
|
||||
cmd := "rpm -qa --queryformat '%{NAME}\t%{VERSION}\t%{RELEASE}\n'"
|
||||
r := o.ssh(cmd, noSudo)
|
||||
r := o.exec(cmd, noSudo)
|
||||
if r.isSuccess() {
|
||||
// e.g.
|
||||
// openssl 1.0.1e 30.el6.11
|
||||
@@ -249,7 +249,7 @@ func (o *redhat) scanUnsecurePackagesUsingYumCheckUpdate() (models.VulnInfos, er
|
||||
cmd = fmt.Sprintf(cmd, "")
|
||||
}
|
||||
|
||||
r := o.ssh(util.PrependProxyEnv(cmd), sudo)
|
||||
r := o.exec(util.PrependProxyEnv(cmd), sudo)
|
||||
if !r.isSuccess(0, 100) {
|
||||
//returns an exit code of 100 if there are available updates.
|
||||
return nil, fmt.Errorf("Failed to SSH: %s", r)
|
||||
@@ -543,7 +543,7 @@ func (o *redhat) getAllChangelog(packInfoList models.PackageInfoList) (stdout st
|
||||
// yum update --changelog doesn't have --color option.
|
||||
command += fmt.Sprintf(" LANGUAGE=en_US.UTF-8 yum %s --changelog update ", yumopts) + packageNames
|
||||
|
||||
r := o.ssh(command, sudo)
|
||||
r := o.exec(command, sudo)
|
||||
if !r.isSuccess(0, 1) {
|
||||
return "", fmt.Errorf(
|
||||
"Failed to get changelog. status: %d, stdout: %s, stderr: %s",
|
||||
@@ -568,7 +568,7 @@ func (o *redhat) scanUnsecurePackagesUsingYumPluginSecurity() (models.VulnInfos,
|
||||
}
|
||||
|
||||
cmd := "yum --color=never repolist"
|
||||
r := o.ssh(util.PrependProxyEnv(cmd), o.sudo())
|
||||
r := o.exec(util.PrependProxyEnv(cmd), o.sudo())
|
||||
if !r.isSuccess() {
|
||||
return nil, fmt.Errorf("Failed to SSH: %s", r)
|
||||
}
|
||||
@@ -584,7 +584,7 @@ func (o *redhat) scanUnsecurePackagesUsingYumPluginSecurity() (models.VulnInfos,
|
||||
} else {
|
||||
cmd = "yum --color=never updateinfo list available --security"
|
||||
}
|
||||
r = o.ssh(util.PrependProxyEnv(cmd), o.sudo())
|
||||
r = o.exec(util.PrependProxyEnv(cmd), o.sudo())
|
||||
if !r.isSuccess() {
|
||||
return nil, fmt.Errorf("Failed to SSH: %s", r)
|
||||
}
|
||||
@@ -593,7 +593,7 @@ func (o *redhat) scanUnsecurePackagesUsingYumPluginSecurity() (models.VulnInfos,
|
||||
// get package name, version, rel to be upgrade.
|
||||
// cmd = "yum check-update --security"
|
||||
cmd = "LANGUAGE=en_US.UTF-8 yum --color=never check-update"
|
||||
r = o.ssh(util.PrependProxyEnv(cmd), o.sudo())
|
||||
r = o.exec(util.PrependProxyEnv(cmd), o.sudo())
|
||||
if !r.isSuccess(0, 100) {
|
||||
//returns an exit code of 100 if there are available updates.
|
||||
return nil, fmt.Errorf("Failed to SSH: %s", r)
|
||||
@@ -628,7 +628,7 @@ func (o *redhat) scanUnsecurePackagesUsingYumPluginSecurity() (models.VulnInfos,
|
||||
} else {
|
||||
cmd = "yum --color=never updateinfo --security update"
|
||||
}
|
||||
r = o.ssh(util.PrependProxyEnv(cmd), o.sudo())
|
||||
r = o.exec(util.PrependProxyEnv(cmd), o.sudo())
|
||||
if !r.isSuccess() {
|
||||
return nil, fmt.Errorf("Failed to SSH: %s", r)
|
||||
}
|
||||
|
||||
@@ -91,47 +91,6 @@ func TestChangeSectionState(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseYumUpdateinfoHeader(t *testing.T) {
|
||||
r := newRedhat(config.ServerInfo{})
|
||||
var tests = []struct {
|
||||
in string
|
||||
out []models.PackageInfo
|
||||
}{
|
||||
{
|
||||
" nodejs-0.10.36-3.el6,libuv-0.10.34-1.el6,v8-3.14.5.10-17.el6 ",
|
||||
[]models.PackageInfo{
|
||||
{
|
||||
Name: "nodejs",
|
||||
Version: "0.10.36",
|
||||
Release: "3.el6",
|
||||
},
|
||||
{
|
||||
Name: "libuv",
|
||||
Version: "0.10.34",
|
||||
Release: "1.el6",
|
||||
},
|
||||
{
|
||||
Name: "v8",
|
||||
Version: "3.14.5.10",
|
||||
Release: "17.el6",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
if a, err := r.parseYumUpdateinfoHeaderCentOS(tt.in); err != nil {
|
||||
t.Errorf("err: %s", err)
|
||||
} else {
|
||||
if !reflect.DeepEqual(a, tt.out) {
|
||||
e := pp.Sprintf("%#v", tt.out)
|
||||
a := pp.Sprintf("%#v", a)
|
||||
t.Errorf("expected %s, actual %s", e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseYumUpdateinfoLineToGetCveIDs(t *testing.T) {
|
||||
r := newRedhat(config.ServerInfo{})
|
||||
var tests = []struct {
|
||||
@@ -804,31 +763,6 @@ if-not-architecture 100-200 amzn-main
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseYumUpdateinfoAmazonLinuxHeader(t *testing.T) {
|
||||
r := newRedhat(config.ServerInfo{})
|
||||
var tests = []struct {
|
||||
in string
|
||||
out models.DistroAdvisory
|
||||
}{
|
||||
{
|
||||
"Amazon Linux AMI 2014.03 - ALAS-2015-598: low priority package update for grep",
|
||||
models.DistroAdvisory{
|
||||
AdvisoryID: "ALAS-2015-598",
|
||||
Severity: "low",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
a, _, _ := r.parseYumUpdateinfoHeaderAmazon(tt.in)
|
||||
if !reflect.DeepEqual(a, tt.out) {
|
||||
e := pp.Sprintf("%v", tt.out)
|
||||
a := pp.Sprintf("%v", a)
|
||||
t.Errorf("expected %s, actual %s", e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseYumUpdateinfoListAvailable(t *testing.T) {
|
||||
r := newRedhat(config.ServerInfo{})
|
||||
rhelStdout := `RHSA-2015:2315 Moderate/Sec. NetworkManager-1:1.0.6-27.el7.x86_64
|
||||
|
||||
@@ -105,6 +105,9 @@ func detectOS(c config.ServerInfo) (osType osTypeInterface) {
|
||||
Log.Debugf("FreeBSD. Host: %s:%s", c.Host, c.Port)
|
||||
return
|
||||
}
|
||||
|
||||
//TODO darwin https://github.com/mizzy/specinfra/blob/master/lib/specinfra/helper/detect_os/darwin.rb
|
||||
|
||||
osType.setServerInfo(c)
|
||||
osType.setErrs([]error{fmt.Errorf("Unknown OS Type")})
|
||||
return
|
||||
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
ex "os/exec"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
@@ -39,7 +39,7 @@ import (
|
||||
"github.com/future-architect/vuls/util"
|
||||
)
|
||||
|
||||
type sshResult struct {
|
||||
type execResult struct {
|
||||
Servername string
|
||||
Host string
|
||||
Port string
|
||||
@@ -50,16 +50,13 @@ type sshResult struct {
|
||||
Error error
|
||||
}
|
||||
|
||||
func (s sshResult) String() string {
|
||||
func (s execResult) String() string {
|
||||
return fmt.Sprintf(
|
||||
"SSHResult: servername: %s, cmd: %s, exitstatus: %d, stdout: %s, stderr: %s, err: %s",
|
||||
"execResult: servername: %s\n cmd: %s\n exitstatus: %d\n stdout: %s\n stderr: %s\n err: %s",
|
||||
s.Servername, s.Cmd, s.ExitStatus, s.Stdout, s.Stderr, s.Error)
|
||||
}
|
||||
|
||||
func (s sshResult) isSuccess(expectedStatusCodes ...int) bool {
|
||||
if s.Error != nil {
|
||||
return false
|
||||
}
|
||||
func (s execResult) isSuccess(expectedStatusCodes ...int) bool {
|
||||
if len(expectedStatusCodes) == 0 {
|
||||
return s.ExitStatus == 0
|
||||
}
|
||||
@@ -68,6 +65,9 @@ func (s sshResult) isSuccess(expectedStatusCodes ...int) bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if s.Error != nil {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -148,8 +148,11 @@ func parallelSSHExec(fn func(osTypeInterface) error, timeoutSec ...int) (errs []
|
||||
return
|
||||
}
|
||||
|
||||
func sshExec(c conf.ServerInfo, cmd string, sudo bool, log ...*logrus.Entry) (result sshResult) {
|
||||
if conf.Conf.SSHExternal {
|
||||
func exec(c conf.ServerInfo, cmd string, sudo bool, log ...*logrus.Entry) (result execResult) {
|
||||
if c.Port == "local" &&
|
||||
(c.Host == "127.0.0.1" || c.Host == "localhost") {
|
||||
result = localExec(c, cmd, sudo)
|
||||
} else if conf.Conf.SSHExternal {
|
||||
result = sshExecExternal(c, cmd, sudo)
|
||||
} else {
|
||||
result = sshExecNative(c, cmd, sudo)
|
||||
@@ -160,7 +163,37 @@ func sshExec(c conf.ServerInfo, cmd string, sudo bool, log ...*logrus.Entry) (re
|
||||
return
|
||||
}
|
||||
|
||||
func sshExecNative(c conf.ServerInfo, cmd string, sudo bool) (result sshResult) {
|
||||
func localExec(c conf.ServerInfo, cmdstr string, sudo bool) (result execResult) {
|
||||
cmdstr = decolateCmd(c, cmdstr, sudo)
|
||||
var cmd *ex.Cmd
|
||||
if c.Distro.Family == "FreeBSD" {
|
||||
cmd = ex.Command("/bin/sh", "-c", cmdstr)
|
||||
} else {
|
||||
cmd = ex.Command("/bin/bash", "-c", cmdstr)
|
||||
}
|
||||
var stdoutBuf, stderrBuf bytes.Buffer
|
||||
cmd.Stdout = &stdoutBuf
|
||||
cmd.Stderr = &stderrBuf
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
result.Error = err
|
||||
if exitError, ok := err.(*ex.ExitError); ok {
|
||||
waitStatus := exitError.Sys().(syscall.WaitStatus)
|
||||
result.ExitStatus = waitStatus.ExitStatus()
|
||||
} else {
|
||||
result.ExitStatus = 999
|
||||
}
|
||||
} else {
|
||||
result.ExitStatus = 0
|
||||
}
|
||||
|
||||
result.Stdout = stdoutBuf.String()
|
||||
result.Stderr = stderrBuf.String()
|
||||
result.Cmd = strings.Replace(cmdstr, "\n", "", -1)
|
||||
return
|
||||
}
|
||||
|
||||
func sshExecNative(c conf.ServerInfo, cmd string, sudo bool) (result execResult) {
|
||||
result.Servername = c.ServerName
|
||||
result.Host = c.Host
|
||||
result.Port = c.Port
|
||||
@@ -219,8 +252,8 @@ func sshExecNative(c conf.ServerInfo, cmd string, sudo bool) (result sshResult)
|
||||
return
|
||||
}
|
||||
|
||||
func sshExecExternal(c conf.ServerInfo, cmd string, sudo bool) (result sshResult) {
|
||||
sshBinaryPath, err := exec.LookPath("ssh")
|
||||
func sshExecExternal(c conf.ServerInfo, cmd string, sudo bool) (result execResult) {
|
||||
sshBinaryPath, err := ex.LookPath("ssh")
|
||||
if err != nil {
|
||||
return sshExecNative(c, cmd, sudo)
|
||||
}
|
||||
@@ -256,13 +289,13 @@ func sshExecExternal(c conf.ServerInfo, cmd string, sudo bool) (result sshResult
|
||||
// cmd = fmt.Sprintf("stty cols 256; set -o pipefail; %s", cmd)
|
||||
|
||||
args = append(args, cmd)
|
||||
execCmd := exec.Command(sshBinaryPath, args...)
|
||||
execCmd := ex.Command(sshBinaryPath, args...)
|
||||
|
||||
var stdoutBuf, stderrBuf bytes.Buffer
|
||||
execCmd.Stdout = &stdoutBuf
|
||||
execCmd.Stderr = &stderrBuf
|
||||
if err := execCmd.Run(); err != nil {
|
||||
if e, ok := err.(*exec.ExitError); ok {
|
||||
if e, ok := err.(*ex.ExitError); ok {
|
||||
if s, ok := e.Sys().(syscall.WaitStatus); ok {
|
||||
result.ExitStatus = s.ExitStatus()
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user