Support SUSE Enterprise Linux (#487)
* Support SUSE Enterprise Linux * Implement Reboot Required detection on SLES * Fix query OVAL because SUSE provides OVAL data each major.minor version * Update README * Support SUSE Enterprise 11
This commit is contained in:
62
Gopkg.lock
generated
62
Gopkg.lock
generated
@@ -4,14 +4,14 @@
|
||||
[[projects]]
|
||||
name = "github.com/Azure/azure-sdk-for-go"
|
||||
packages = ["storage"]
|
||||
revision = "57db66900881e9fd21fd041a9d013514700ecab3"
|
||||
version = "v10.3.0-beta"
|
||||
revision = "df4dd90d076ebbf6e87d08d3f00bfac8ff4bde1a"
|
||||
version = "v10.3.1-beta"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/Azure/go-autorest"
|
||||
packages = ["autorest","autorest/adal","autorest/azure","autorest/date"]
|
||||
revision = "77a52603f06947221c672f10275abc9bf2c7d557"
|
||||
version = "v8.3.0"
|
||||
revision = "f6be1abbb5abd0517522f850dd785990d373da7e"
|
||||
version = "v8.4.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/BurntSushi/toml"
|
||||
@@ -28,8 +28,8 @@
|
||||
[[projects]]
|
||||
name = "github.com/aws/aws-sdk-go"
|
||||
packages = ["aws","aws/awserr","aws/awsutil","aws/client","aws/client/metadata","aws/corehandlers","aws/credentials","aws/credentials/ec2rolecreds","aws/credentials/endpointcreds","aws/credentials/stscreds","aws/defaults","aws/ec2metadata","aws/endpoints","aws/request","aws/session","aws/signer/v4","internal/shareddefaults","private/protocol","private/protocol/query","private/protocol/query/queryutil","private/protocol/rest","private/protocol/restxml","private/protocol/xml/xmlutil","service/s3","service/sts"]
|
||||
revision = "264af29009637e0a9e5d4a276d0969c3ed918ffd"
|
||||
version = "v1.10.29"
|
||||
revision = "b69f447375c7fa0047ebcdd8ae5d585d5aac2f71"
|
||||
version = "v1.10.51"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/boltdb/bolt"
|
||||
@@ -46,8 +46,8 @@
|
||||
[[projects]]
|
||||
name = "github.com/cheggaaa/pb"
|
||||
packages = ["."]
|
||||
revision = "0d6285554e726cc0620cbecc7e6969c945dcc63b"
|
||||
version = "v1.0.17"
|
||||
revision = "657164d0228d6bebe316fdf725c69f131a50fb10"
|
||||
version = "v1.0.18"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/dgrijalva/jwt-go"
|
||||
@@ -64,8 +64,8 @@
|
||||
[[projects]]
|
||||
name = "github.com/go-redis/redis"
|
||||
packages = [".","internal","internal/consistenthash","internal/hashtag","internal/pool","internal/proto"]
|
||||
revision = "19c1c2272e00c1aaa903cf574c746cd449f9cd3c"
|
||||
version = "v6.5.7"
|
||||
revision = "975882d73d21759d45a4eb49652064083bc23e61"
|
||||
version = "v6.7.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/go-sql-driver/mysql"
|
||||
@@ -137,7 +137,7 @@
|
||||
branch = "master"
|
||||
name = "github.com/kotakanbe/go-cve-dictionary"
|
||||
packages = ["config","db","jvn","log","models","nvd","util"]
|
||||
revision = "c20fa7e1d07f7c700baf12c855f7fcf61525f1b6"
|
||||
revision = "f5406ffe8226f01f64544723339c6a17b2bd74af"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/kotakanbe/go-pingscanner"
|
||||
@@ -149,7 +149,7 @@
|
||||
branch = "master"
|
||||
name = "github.com/kotakanbe/goval-dictionary"
|
||||
packages = ["config","db","db/rdb","log","models"]
|
||||
revision = "3523cc174e68f285d0572d07c68ffa3a9290799c"
|
||||
revision = "a9de1f6e9126c5e75b46b39e4049624cde8c8bb4"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
@@ -157,17 +157,11 @@
|
||||
packages = ["."]
|
||||
revision = "75edb2e85a38873f0318be05a458446681d1022f"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/labstack/gommon"
|
||||
packages = ["color","log"]
|
||||
revision = "779b8a8b9850a97acba6a3fe20feb628c39e17c1"
|
||||
version = "0.2.2"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/lib/pq"
|
||||
packages = [".","hstore","oid"]
|
||||
revision = "e42267488fe361b9dc034be7a6bffef5b195bceb"
|
||||
revision = "b77235e3890a962fe8a6f8c4c7198679ca7814e7"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mattn/go-colorable"
|
||||
@@ -178,8 +172,8 @@
|
||||
[[projects]]
|
||||
name = "github.com/mattn/go-isatty"
|
||||
packages = ["."]
|
||||
revision = "fc9e8d8ef48496124e79ae0df75490096eccf6fe"
|
||||
version = "v0.0.2"
|
||||
revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39"
|
||||
version = "v0.0.3"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mattn/go-runewidth"
|
||||
@@ -203,7 +197,7 @@
|
||||
branch = "master"
|
||||
name = "github.com/moul/http2curl"
|
||||
packages = ["."]
|
||||
revision = "4e24498b31dba4683efb9d35c1c8a91e2eda28c8"
|
||||
revision = "9ac6cf4d929b2fa8fd2d2e6dec5bb0feb4f4911d"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
@@ -239,19 +233,7 @@
|
||||
branch = "master"
|
||||
name = "github.com/sirupsen/logrus"
|
||||
packages = ["."]
|
||||
revision = "84573d5f03ab3740f524c7842c3a9bf617961d32"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/valyala/bytebufferpool"
|
||||
packages = ["."]
|
||||
revision = "e746df99fe4a3986f4d4f79e13c1e0117ce9c2f7"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/valyala/fasttemplate"
|
||||
packages = ["."]
|
||||
revision = "dcecefd839c4193db0d35b88ec65b4c12d360ab0"
|
||||
revision = "89742aefa4b206dcf400792f3bd35b542998eb3b"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
@@ -263,25 +245,25 @@
|
||||
branch = "master"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = ["curve25519","ed25519","ed25519/internal/edwards25519","ssh","ssh/agent","ssh/terminal"]
|
||||
revision = "eb71ad9bd329b5ac0fd0148dd99bd62e8be8e035"
|
||||
revision = "847319b7fc94cab682988f93da778204da164588"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/net"
|
||||
packages = ["context","idna","publicsuffix"]
|
||||
revision = "1c05540f6879653db88113bc4a2b70aec4bd491f"
|
||||
revision = "0744d001aa8470aaa53df28d32e5ceeb8af9bd70"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sys"
|
||||
packages = ["unix","windows"]
|
||||
revision = "07c182904dbd53199946ba614a412c61d3c548f5"
|
||||
revision = "429f518978ab01db8bb6f44b66785088e7fba58b"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/text"
|
||||
packages = ["internal/gen","internal/triegen","internal/ucd","secure/bidirule","transform","unicode/bidi","unicode/cldr","unicode/norm","unicode/rangetable"]
|
||||
revision = "e56139fd9c5bc7244c76116c68e500765bb6db6b"
|
||||
packages = ["collate","collate/build","internal/colltab","internal/gen","internal/tag","internal/triegen","internal/ucd","language","secure/bidirule","transform","unicode/bidi","unicode/cldr","unicode/norm","unicode/rangetable"]
|
||||
revision = "1cbadb444a806fd9430d14ad08967ed91da4fa0a"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
|
||||
28
README.ja.md
28
README.ja.md
@@ -139,7 +139,7 @@ Vulsは上に挙げた手動運用での課題を解決するツールであり
|
||||
# Main Features
|
||||
|
||||
- サーバに存在する脆弱性をスキャン
|
||||
- FreeBSD, Ubuntu, Debian, CentOS, Amazon Linux, RHEL, Raspbianに対応
|
||||
- FreeBSD, Ubuntu, Debian, CentOS, Amazon Linux, RHEL, Oracle Linux, SUSE Enterprise, Raspbianに対応
|
||||
- クラウド、オンプレミス、Docker
|
||||
- 高精度なスキャン
|
||||
- Vulsは複数の脆弱性データベース、複数の検知方法を組み合わせることで高精度なスキャンを実現している
|
||||
@@ -328,6 +328,7 @@ $ goval-dictionary fetch-redhat 7
|
||||
- [Debian](https://github.com/kotakanbe/goval-dictionary#usage-fetch-oval-data-from-debian)
|
||||
- [Ubuntu](https://github.com/kotakanbe/goval-dictionary#usage-fetch-oval-data-from-ubuntu)
|
||||
- [Oracle Linux](https://github.com/kotakanbe/goval-dictionary#usage-fetch-oval-data-from-oracle)
|
||||
- [SUSE](https://github.com/kotakanbe/goval-dictionary#usage-fetch-oval-data-from-suse)
|
||||
|
||||
## Step5. Deploy Vuls
|
||||
|
||||
@@ -586,9 +587,10 @@ Vulsをスキャン対象サーバにデプロイする。Vulsはローカルホ
|
||||
| Oracle | Fast | No | Supported | No |
|
||||
| Ubuntu | Fast | No | Supported | No |
|
||||
| Debian | Fast | No | Supported | No |
|
||||
| Raspbian |1st time: Slow <br> From 2nd time: Fast | Need | No | Need |
|
||||
| FreeBSD | Fast | No | No | Need |
|
||||
| Amazon | Fast | No | No | Need |
|
||||
| Raspbian |1st time: Slow <br> From 2nd time: Fast | Need | No | Need |
|
||||
| SUSE Enterprise | Fast | No | Supported | No|
|
||||
|
||||
----
|
||||
|
||||
@@ -604,22 +606,26 @@ Vulsをスキャン対象サーバにデプロイする。Vulsはローカルホ
|
||||
| Oracle | Slow | Need | Supported | Need |
|
||||
| Ubuntu |1st time: Slow <br> From 2nd time: Fast| Need | Supported | Need |
|
||||
| Debian |1st time: Slow <br> From 2nd time: Fast| Need | Supported | Need |
|
||||
| Raspbian |1st time: Slow <br> From 2nd time: Fast| Need | No | Need |
|
||||
| FreeBSD | Fast | No | No | Need |
|
||||
| Amazon | Slow | No | No | Need |
|
||||
| Raspbian |1st time: Slow <br> From 2nd time: Fast| Need | No | Need |
|
||||
| SUSE Enterprise | Fast | No | Supported | No|
|
||||
|
||||
|
||||
- Ubuntu, Debian, Raspbian
|
||||
- On Ubuntu, Debian and Raspbian
|
||||
`apt-get changelog`でアップデート対象のパッケージのチェンジログを取得し、含まれるCVE IDをパースする。
|
||||
アップデート対象のパッケージが沢山ある場合、チェンジログの取得に時間がかかるので、初回のスキャンは遅い。
|
||||
ただ、2回目以降はキャッシュしたchangelogを使うので速くなる。
|
||||
|
||||
- CentOS
|
||||
- On CentOS
|
||||
`yum changelog`でアップデート対象のパッケージのチェンジログを取得し、含まれるCVE IDをパースする。
|
||||
|
||||
- Amazon, RHEL and FreeBSD
|
||||
- On RHEL, Oracle, Amazon and FreeBSD
|
||||
`yum changelog`でアップデート対象のパッケージのチェンジログを取得する(パースはしない)。
|
||||
|
||||
- On SUSE Enterprise Linux
|
||||
Same as fast scan mode for now.
|
||||
|
||||
----
|
||||
|
||||
# Use Cases
|
||||
@@ -646,6 +652,7 @@ web/app server in the same configuration under the load balancer
|
||||
| CentOS | 6, 7|
|
||||
| Amazon Linux| All|
|
||||
| FreeBSD | 10, 11|
|
||||
| SUSE Enterprise | 11, 12|
|
||||
| Raspbian | Jessie, Stretch |
|
||||
|
||||
----
|
||||
@@ -882,6 +889,7 @@ configtestサブコマンドは、config.tomlで定義されたサーバ/コン
|
||||
| Amazon | All | - |
|
||||
| RHEL | 5, 6, 7 | - |
|
||||
| Oracle Linux | 5, 6, 7 | - |
|
||||
| SUSE Enterprise| 11, 12 | - |
|
||||
| FreeBSD | 10, 11 | - |
|
||||
| Raspbian | Jessie, Stretch | - |
|
||||
|
||||
@@ -899,13 +907,14 @@ Deep Scan Modeでスキャンするためには、下記のパッケージが必
|
||||
| Distribution | Release | Requirements |
|
||||
|:-------------|-------------------:|:-------------|
|
||||
| Ubuntu | 12, 14, 16| - |
|
||||
| Debian | 7, 8, 9| aptitude, reboot-notifier |
|
||||
| Debian | 7, 8, 9| aptitude, reboot-notifier |
|
||||
| CentOS | 6, 7| yum-plugin-changelog, yum-utils |
|
||||
| Amazon | All | yum-plugin-changelog, yum-utils |
|
||||
| RHEL | 5 | yum-utils, yum-security, yum-changelog |
|
||||
| RHEL | 6, 7 | yum-utils, yum-plugin-changelog |
|
||||
| Oracle Linux | 5 | yum-utils, yum-security, yum-changelog |
|
||||
| Oracle Linux | 6, 7 | yum-utils, yum-plugin-changelog |
|
||||
| SUSE Enterprise| 11, 12 | - |
|
||||
| FreeBSD | 10 | - |
|
||||
| Raspbian | Wheezy, Jessie | - |
|
||||
|
||||
@@ -935,7 +944,7 @@ vuls ALL=(ALL) NOPASSWD: /usr/bin/apt-get update
|
||||
Defaults:vuls env_keep="http_proxy https_proxy HTTP_PROXY HTTPS_PROXY"
|
||||
```
|
||||
|
||||
- CentOS, Amazon Linux, FreeBSDは今のところRoot権限なしでスキャン可能
|
||||
- CentOS, Amazon Linux, SUSE Enterprise, FreeBSDは今のところRoot権限なしでスキャン可能
|
||||
|
||||
----
|
||||
|
||||
@@ -1338,7 +1347,7 @@ Confidence 100 / OvalMatch
|
||||
|
||||
| Detection Method | Confidence | OS |Description|
|
||||
|:-----------------------|-------------------:|:---------------------------------|:--|
|
||||
| OvalMatch | 100 | CentOS, RHEL, Oracle, Ubuntu, Debian |Detection using OVAL |
|
||||
| OvalMatch | 100 | CentOS, RHEL, Oracle, Ubuntu, Debian, SUSE |Detection using OVAL |
|
||||
| YumUpdateSecurityMatch | 100 | RHEL, Amazon, Oracle |Detection using yum-plugin-security|
|
||||
| ChangelogExactMatch | 95 | CentOS, Ubuntu, Debian, Raspbian |Exact version match between changelog and package version|
|
||||
| ChangelogLenientMatch | 50 | Ubuntu, Debian, Raspbian |Lenient version match between changelog and package version|
|
||||
@@ -1713,6 +1722,7 @@ $ vuls report -ovaldb-url=http://192.168.0.1:1323
|
||||
- [Ubuntu](https://github.com/kotakanbe/goval-dictionary#usage-fetch-oval-data-from-ubuntu)
|
||||
- [Debian](https://github.com/kotakanbe/goval-dictionary#usage-fetch-oval-data-from-debian)
|
||||
- [Oracle](https://github.com/kotakanbe/goval-dictionary#usage-fetch-oval-data-from-oracle)
|
||||
- [SUSE](https://github.com/kotakanbe/goval-dictionary#usage-fetch-oval-data-from-suse)
|
||||
|
||||
----
|
||||
|
||||
|
||||
17
README.md
17
README.md
@@ -144,7 +144,7 @@ Vuls is a tool created to solve the problems listed above. It has the following
|
||||
# Main Features
|
||||
|
||||
- Scan for any vulnerabilities in Linux/FreeBSD Server
|
||||
- Supports FreeBSD, Ubuntu, Debian, CentOS, Amazon Linux, RHEL, Oracle Linux and Raspbian
|
||||
- Supports FreeBSD, Ubuntu, Debian, CentOS, Amazon Linux, RHEL, Oracle Linux, SUSE Enterprise Linux and Raspbian
|
||||
- Cloud, on-premise, Docker
|
||||
- High quality scan
|
||||
- Vuls uses Multiple vulnerability databases
|
||||
@@ -335,6 +335,7 @@ If you want to scan other than CentOS 7, fetch OVAL data according to the OS typ
|
||||
- [Debian](https://github.com/kotakanbe/goval-dictionary#usage-fetch-oval-data-from-debian)
|
||||
- [Ubuntu](https://github.com/kotakanbe/goval-dictionary#usage-fetch-oval-data-from-ubuntu)
|
||||
- [Oracle Linux](https://github.com/kotakanbe/goval-dictionary#usage-fetch-oval-data-from-oracle)
|
||||
- [SUSE](https://github.com/kotakanbe/goval-dictionary#usage-fetch-oval-data-from-suse)
|
||||
|
||||
## Step5. Deploy Vuls
|
||||
|
||||
@@ -597,6 +598,7 @@ On the aggregation server, you can refer to the scanning result of each scan tar
|
||||
| Raspbian |1st time: Slow <br> From 2nd time: Fast | Need | No | Need |
|
||||
| FreeBSD | Fast | No | No | Need |
|
||||
| Amazon | Fast | No | No | Need |
|
||||
| SUSE Enterprise | Fast | No | Supported | No|
|
||||
|
||||
|
||||
---------
|
||||
@@ -614,6 +616,7 @@ On the aggregation server, you can refer to the scanning result of each scan tar
|
||||
| Raspbian |1st time: Slow <br> From 2nd time: Fast| Need | No | Need |
|
||||
| FreeBSD | Fast | No | No | Need |
|
||||
| Amazon | Slow | No | No | Need |
|
||||
| SUSE Enterprise | Fast | No | Supported | No|
|
||||
|
||||
|
||||
- On Ubuntu, Debian and Raspbian
|
||||
@@ -624,9 +627,13 @@ From the second time on, the scan speed is fast by using the local cache.
|
||||
|
||||
- On CentOS
|
||||
Vuls issues `yum changelog` to get changelogs of upgradable packages at once and parse the changelog.
|
||||
|
||||
- On RHEL, Oracle, Amazon and FreeBSD
|
||||
Detect CVE IDs by using package manager.
|
||||
|
||||
- On SUSE Enterprise Linux
|
||||
Same as fast scan mode for now.
|
||||
|
||||
----
|
||||
|
||||
# Use Cases
|
||||
@@ -658,6 +665,7 @@ If there is a staging environment with the same configuration as the production
|
||||
| CentOS | 6, 7|
|
||||
| Amazon Linux | All|
|
||||
| FreeBSD | 10, 11|
|
||||
| SUSE Enterprise | 11, 12|
|
||||
| Raspbian | Jessie, Stretch |
|
||||
|
||||
----
|
||||
@@ -893,6 +901,7 @@ The configtest subcommand checks whether vuls is able to connect via SSH to serv
|
||||
| Amazon | All | - |
|
||||
| RHEL | 5, 6, 7 | - |
|
||||
| Oracle Linux | 5, 6, 7 | - |
|
||||
| SUSE Enterprise| 11, 12 | - |
|
||||
| FreeBSD | 10, 11 | - |
|
||||
| Raspbian | Jessie, Stretch | - |
|
||||
|
||||
@@ -915,6 +924,7 @@ In order to scan with deep scan mode, the following dependencies are required, s
|
||||
| RHEL | 6, 7 | yum-utils, yum-plugin-changelog |
|
||||
| Oracle Linux | 5 | yum-utils, yum-security, yum-changelog |
|
||||
| Oracle Linux | 6, 7 | yum-utils, yum-plugin-changelog |
|
||||
| SUSE Enterprise| 11, 12 | - |
|
||||
| FreeBSD | 10 | - |
|
||||
| Raspbian | Wheezy, Jessie | - |
|
||||
|
||||
@@ -944,7 +954,7 @@ vuls ALL=(ALL) NOPASSWD: /usr/bin/apt-get update
|
||||
Defaults:vuls env_keep="http_proxy https_proxy HTTP_PROXY HTTPS_PROXY"
|
||||
```
|
||||
|
||||
- On CentOS, Amazon Linux, FreeBSD, it is possible to scan without root privilege for now.
|
||||
- On CentOS, Amazon Linux, SUSE Enterprise, FreeBSD, it is possible to scan without root privilege for now.
|
||||
|
||||
----
|
||||
|
||||
@@ -1349,7 +1359,7 @@ Confidence 100 / OvalMatch
|
||||
|
||||
| Detection Method | Confidence | OS |Description|
|
||||
|:-----------------------|-------------------:|:---------------------------------|:--|
|
||||
| OvalMatch | 100 | CentOS, RHEL, Oracle, Ubuntu, Debian |Detection using OVAL |
|
||||
| OvalMatch | 100 | CentOS, RHEL, Oracle, Ubuntu, Debian, SUSE |Detection using OVAL |
|
||||
| YumUpdateSecurityMatch | 100 | RHEL, Amazon, Oracle |Detection using yum-plugin-security|
|
||||
| ChangelogExactMatch | 95 | CentOS, Ubuntu, Debian, Raspbian |Exact version match between changelog and package version|
|
||||
| ChangelogLenientMatch | 50 | Ubuntu, Debian, Raspbian |Lenient version match between changelog and package version|
|
||||
@@ -1712,6 +1722,7 @@ $ vuls report -ovaldb-url=http://192.168.0.1:1323
|
||||
- [Ubuntu](https://github.com/kotakanbe/goval-dictionary#usage-fetch-oval-data-from-ubuntu)
|
||||
- [Debian](https://github.com/kotakanbe/goval-dictionary#usage-fetch-oval-data-from-debian)
|
||||
- [Oracle](https://github.com/kotakanbe/goval-dictionary#usage-fetch-oval-data-from-oracle)
|
||||
- [SUSE](https://github.com/kotakanbe/goval-dictionary#usage-fetch-oval-data-from-suse)
|
||||
|
||||
----
|
||||
|
||||
|
||||
@@ -61,6 +61,21 @@ const (
|
||||
|
||||
// Windows is
|
||||
Windows = "windows"
|
||||
|
||||
// OpenSUSE is
|
||||
OpenSUSE = "opensuse"
|
||||
|
||||
// OpenSUSELeap is
|
||||
OpenSUSELeap = "opensuse.leap"
|
||||
|
||||
// SUSEEnterpriseServer is
|
||||
SUSEEnterpriseServer = "suse.linux.enterprise.server"
|
||||
|
||||
// SUSEEnterpriseDesktop is
|
||||
SUSEEnterpriseDesktop = "suse.linux.enterprise.desktop"
|
||||
|
||||
// SUSEOpenstackCloud is
|
||||
SUSEOpenstackCloud = "suse.openstack.cloud"
|
||||
)
|
||||
|
||||
//Config is struct of Configuration
|
||||
|
||||
@@ -229,6 +229,9 @@ const (
|
||||
// Oracle is Oracle Linux
|
||||
Oracle CveContentType = "oracle"
|
||||
|
||||
// SUSE is SUSE Linux
|
||||
SUSE CveContentType = "suse"
|
||||
|
||||
// Unknown is Unknown
|
||||
Unknown CveContentType = "unknown"
|
||||
)
|
||||
|
||||
@@ -546,6 +546,8 @@ func (v VulnInfo) VendorLinks(family string) map[string]string {
|
||||
return links
|
||||
case config.Debian:
|
||||
links["Debian-CVE"] = "https://security-tracker.debian.org/tracker/" + v.CveID
|
||||
case config.SUSEEnterpriseServer:
|
||||
links["SUSE-CVE"] = "https://www.suse.com/security/cve/" + v.CveID
|
||||
case config.FreeBSD:
|
||||
for _, advisory := range v.DistroAdvisories {
|
||||
links["FreeBSD-VuXML"] = fmt.Sprintf("https://vuxml.freebsd.org/freebsd/%s.html", advisory.AdvisoryID)
|
||||
|
||||
119
oval/suse.go
Normal file
119
oval/suse.go
Normal file
@@ -0,0 +1,119 @@
|
||||
/* Vuls - Vulnerability Scanner
|
||||
Copyright (C) 2016 Future Architect, Inc. Japan.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package oval
|
||||
|
||||
import (
|
||||
"github.com/future-architect/vuls/config"
|
||||
"github.com/future-architect/vuls/models"
|
||||
"github.com/future-architect/vuls/util"
|
||||
ovalmodels "github.com/kotakanbe/goval-dictionary/models"
|
||||
)
|
||||
|
||||
// SUSE is the struct of SUSE Linux
|
||||
type SUSE struct {
|
||||
Base
|
||||
}
|
||||
|
||||
// NewSUSE creates OVAL client for SUSE
|
||||
func NewSUSE() SUSE {
|
||||
// TODO implement other family
|
||||
return SUSE{
|
||||
Base{
|
||||
family: config.SUSEEnterpriseServer,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// FillWithOval returns scan result after updating CVE info by OVAL
|
||||
func (o SUSE) FillWithOval(r *models.ScanResult) (err error) {
|
||||
var relatedDefs ovalResult
|
||||
if o.isFetchViaHTTP() {
|
||||
if relatedDefs, err = getDefsByPackNameViaHTTP(r); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if relatedDefs, err = getDefsByPackNameFromOvalDB(o.family, r.Release, r.Packages); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, defPacks := range relatedDefs.entries {
|
||||
o.update(r, defPacks)
|
||||
}
|
||||
|
||||
for _, vuln := range r.ScannedCves {
|
||||
if cont, ok := vuln.CveContents[models.SUSE]; ok {
|
||||
cont.SourceLink = "https://security-tracker.debian.org/tracker/" + cont.CveID
|
||||
vuln.CveContents[models.SUSE] = cont
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o SUSE) update(r *models.ScanResult, defPacks defPacks) {
|
||||
ovalContent := *o.convertToModel(&defPacks.def)
|
||||
ovalContent.Type = models.NewCveContentType(o.family)
|
||||
vinfo, ok := r.ScannedCves[defPacks.def.Title]
|
||||
if !ok {
|
||||
util.Log.Debugf("%s is newly detected by OVAL", defPacks.def.Title)
|
||||
vinfo = models.VulnInfo{
|
||||
CveID: defPacks.def.Title,
|
||||
Confidence: models.OvalMatch,
|
||||
CveContents: models.NewCveContents(ovalContent),
|
||||
}
|
||||
} else {
|
||||
cveContents := vinfo.CveContents
|
||||
ctype := models.NewCveContentType(o.family)
|
||||
if _, ok := vinfo.CveContents[ctype]; ok {
|
||||
util.Log.Debugf("%s OVAL will be overwritten", defPacks.def.Title)
|
||||
} else {
|
||||
util.Log.Debugf("%s is also detected by OVAL", defPacks.def.Title)
|
||||
cveContents = models.CveContents{}
|
||||
}
|
||||
if vinfo.Confidence.Score < models.OvalMatch.Score {
|
||||
vinfo.Confidence = models.OvalMatch
|
||||
}
|
||||
cveContents[ctype] = ovalContent
|
||||
vinfo.CveContents = cveContents
|
||||
}
|
||||
|
||||
// uniq(vinfo.PackNames + defPacks.actuallyAffectedPackNames)
|
||||
for _, pack := range vinfo.AffectedPackages {
|
||||
defPacks.actuallyAffectedPackNames[pack.Name] = true
|
||||
}
|
||||
vinfo.AffectedPackages = defPacks.toPackStatuses(r.Family, r.Packages)
|
||||
vinfo.AffectedPackages.Sort()
|
||||
r.ScannedCves[defPacks.def.Title] = vinfo
|
||||
}
|
||||
|
||||
func (o SUSE) convertToModel(def *ovalmodels.Definition) *models.CveContent {
|
||||
var refs []models.Reference
|
||||
for _, r := range def.References {
|
||||
refs = append(refs, models.Reference{
|
||||
Link: r.RefURL,
|
||||
Source: r.Source,
|
||||
RefID: r.RefID,
|
||||
})
|
||||
}
|
||||
|
||||
return &models.CveContent{
|
||||
CveID: def.Title,
|
||||
Title: def.Title,
|
||||
Summary: def.Description,
|
||||
References: refs,
|
||||
}
|
||||
}
|
||||
@@ -323,10 +323,12 @@ func lessThan(family string, packA models.Package, packB ovalmodels.Package) (bo
|
||||
return false, err
|
||||
}
|
||||
return vera.LessThan(verb), nil
|
||||
case config.RedHat, config.CentOS, config.Oracle:
|
||||
case config.RedHat, config.CentOS, config.Oracle, config.SUSEEnterpriseServer:
|
||||
vera := rpmver.NewVersion(fmt.Sprintf("%s-%s", packA.Version, packA.Release))
|
||||
verb := rpmver.NewVersion(packB.Version)
|
||||
return vera.LessThan(verb), nil
|
||||
default:
|
||||
util.Log.Errorf("Not implemented yet: %s", family)
|
||||
}
|
||||
return false, fmt.Errorf("Package version comparison not supported: %s", family)
|
||||
}
|
||||
|
||||
@@ -173,6 +173,10 @@ func FillWithOval(r *models.ScanResult) (err error) {
|
||||
case c.Oracle:
|
||||
ovalClient = oval.NewOracle()
|
||||
ovalFamily = c.Oracle
|
||||
case c.SUSEEnterpriseServer:
|
||||
// TODO other suse family
|
||||
ovalClient = oval.NewSUSE()
|
||||
ovalFamily = c.SUSEEnterpriseServer
|
||||
case c.Amazon, c.Raspbian, c.FreeBSD, c.Windows:
|
||||
return nil
|
||||
default:
|
||||
|
||||
@@ -280,14 +280,7 @@ func (o *redhat) scanInstalledPackages() (models.Packages, error) {
|
||||
}
|
||||
|
||||
installed := models.Packages{}
|
||||
var cmd string
|
||||
majorVersion, _ := o.Distro.MajorVersion()
|
||||
if majorVersion < 6 {
|
||||
cmd = "rpm -qa --queryformat '%{NAME} %{EPOCH} %{VERSION} %{RELEASE} %{ARCH}\n'"
|
||||
} else {
|
||||
cmd = "rpm -qa --queryformat '%{NAME} %{EPOCHNUM} %{VERSION} %{RELEASE} %{ARCH}\n'"
|
||||
}
|
||||
r := o.exec(cmd, noSudo)
|
||||
r := o.exec(rpmQa(o.Distro), noSudo)
|
||||
if !r.isSuccess() {
|
||||
return nil, fmt.Errorf("Scan packages failed: %s", r)
|
||||
}
|
||||
@@ -304,14 +297,13 @@ func (o *redhat) scanInstalledPackages() (models.Packages, error) {
|
||||
// Kernel package may be isntalled multiple versions.
|
||||
// From the viewpoint of vulnerability detection,
|
||||
// pay attention only to the running kernel
|
||||
if pack.Name == "kernel" {
|
||||
ver := fmt.Sprintf("%s-%s.%s", pack.Version, pack.Release, pack.Arch)
|
||||
if o.Kernel.Release != ver {
|
||||
o.log.Debugf("Not a running kernel: %s, uname: %s", ver, release)
|
||||
isKernel, running := isRunningKernel(pack, o.Distro.Family, o.Kernel)
|
||||
if isKernel {
|
||||
if !running {
|
||||
o.log.Debugf("Not a running kernel. pack: %#v, kernel: %#v", pack, o.Kernel)
|
||||
continue
|
||||
} else {
|
||||
o.log.Debugf("Running kernel: %s, uname: %s", ver, release)
|
||||
}
|
||||
o.log.Debugf("Found a running kernel. pack: %#v, kernel: %#v", pack, o.Kernel)
|
||||
}
|
||||
installed[pack.Name] = pack
|
||||
}
|
||||
|
||||
@@ -89,6 +89,11 @@ func detectOS(c config.ServerInfo) (osType osTypeInterface) {
|
||||
return
|
||||
}
|
||||
|
||||
if itsMe, osType = detectSUSE(c); itsMe {
|
||||
util.Log.Debugf("SUSE Linux. Host: %s:%s", c.Host, c.Port)
|
||||
return
|
||||
}
|
||||
|
||||
if itsMe, osType = detectFreebsd(c); itsMe {
|
||||
util.Log.Debugf("FreeBSD. Host: %s:%s", c.Host, c.Port)
|
||||
return
|
||||
|
||||
185
scan/suse.go
Normal file
185
scan/suse.go
Normal file
@@ -0,0 +1,185 @@
|
||||
package scan
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/future-architect/vuls/config"
|
||||
"github.com/future-architect/vuls/models"
|
||||
"github.com/future-architect/vuls/util"
|
||||
)
|
||||
|
||||
// inherit OsTypeInterface
|
||||
type suse struct {
|
||||
redhat
|
||||
}
|
||||
|
||||
// NewRedhat is constructor
|
||||
func newSUSE(c config.ServerInfo) *suse {
|
||||
r := &suse{
|
||||
redhat: redhat{
|
||||
base: base{
|
||||
osPackages: osPackages{
|
||||
Packages: models.Packages{},
|
||||
VulnInfos: models.VulnInfos{},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
r.log = util.NewCustomLogger(c)
|
||||
r.setServerInfo(c)
|
||||
return r
|
||||
}
|
||||
|
||||
// https://github.com/mizzy/specinfra/blob/master/lib/specinfra/helper/detect_os/suse.rb
|
||||
func detectSUSE(c config.ServerInfo) (itsMe bool, suse osTypeInterface) {
|
||||
suse = newSUSE(c)
|
||||
|
||||
if r := exec(c, "ls /etc/os-release", noSudo); r.isSuccess() {
|
||||
if r := exec(c, "zypper -V", noSudo); r.isSuccess() {
|
||||
if r := exec(c, "cat /etc/os-release", noSudo); r.isSuccess() {
|
||||
name := ""
|
||||
if strings.Contains(r.Stdout, "ID=opensuse") {
|
||||
//TODO check opensuse or opensuse.leap
|
||||
name = config.OpenSUSE
|
||||
} else if strings.Contains(r.Stdout, `NAME="SLES"`) {
|
||||
name = config.SUSEEnterpriseServer
|
||||
} else {
|
||||
util.Log.Warn("Failed to parse SUSE edition: %s", r)
|
||||
return true, suse
|
||||
}
|
||||
|
||||
re := regexp.MustCompile(`VERSION_ID=\"(\d+\.\d+|\d+)\"`)
|
||||
result := re.FindStringSubmatch(strings.TrimSpace(r.Stdout))
|
||||
if len(result) != 2 {
|
||||
util.Log.Warn("Failed to parse SUSE Linux version: %s", r)
|
||||
return true, suse
|
||||
}
|
||||
suse.setDistro(name, result[1])
|
||||
return true, suse
|
||||
}
|
||||
}
|
||||
} else if r := exec(c, "ls /etc/SuSE-release", noSudo); r.isSuccess() {
|
||||
if r := exec(c, "zypper -V", noSudo); r.isSuccess() {
|
||||
if r := exec(c, "cat /etc/SuSE-release", noSudo); r.isSuccess() {
|
||||
re := regexp.MustCompile(`openSUSE (\d+\.\d+|\d+)`)
|
||||
result := re.FindStringSubmatch(strings.TrimSpace(r.Stdout))
|
||||
if len(result) == 2 {
|
||||
//TODO check opensuse or opensuse.leap
|
||||
suse.setDistro(config.OpenSUSE, result[1])
|
||||
return true, suse
|
||||
}
|
||||
|
||||
re = regexp.MustCompile(`VERSION = (\d+)`)
|
||||
result = re.FindStringSubmatch(strings.TrimSpace(r.Stdout))
|
||||
if len(result) == 2 {
|
||||
version := result[1]
|
||||
re = regexp.MustCompile(`PATCHLEVEL = (\d+)`)
|
||||
result = re.FindStringSubmatch(strings.TrimSpace(r.Stdout))
|
||||
if len(result) == 2 {
|
||||
suse.setDistro(config.SUSEEnterpriseServer,
|
||||
fmt.Sprintf("%s.%s", version, result[1]))
|
||||
return true, suse
|
||||
}
|
||||
}
|
||||
util.Log.Warn("Failed to parse SUSE Linux version: %s", r)
|
||||
return true, suse
|
||||
}
|
||||
}
|
||||
}
|
||||
util.Log.Debugf("Not SUSE Linux. servername: %s", c.ServerName)
|
||||
return false, suse
|
||||
}
|
||||
|
||||
func (o *suse) checkDependencies() error {
|
||||
o.log.Infof("Dependencies... No need")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *suse) checkIfSudoNoPasswd() error {
|
||||
// SUSE doesn't need root privilege
|
||||
o.log.Infof("sudo ... No need")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *suse) scanPackages() error {
|
||||
installed, err := o.scanInstalledPackages()
|
||||
if err != nil {
|
||||
o.log.Errorf("Failed to scan installed packages: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
rebootRequired, err := o.rebootRequired()
|
||||
if err != nil {
|
||||
o.log.Errorf("Failed to detect the kernel reboot required: %s", err)
|
||||
return err
|
||||
}
|
||||
o.Kernel.RebootRequired = rebootRequired
|
||||
|
||||
updatable, err := o.scanUpdatablePackages()
|
||||
if err != nil {
|
||||
o.log.Errorf("Failed to scan updatable packages: %s", err)
|
||||
return err
|
||||
}
|
||||
installed.MergeNewVersion(updatable)
|
||||
o.Packages = installed
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *suse) rebootRequired() (bool, error) {
|
||||
r := o.exec("rpm -q --last kernel-default | head -n1", noSudo)
|
||||
if !r.isSuccess() {
|
||||
return false, fmt.Errorf("Failed to detect the last installed kernel : %v", r)
|
||||
}
|
||||
stdout := strings.Fields(r.Stdout)[0]
|
||||
return !strings.Contains(stdout, strings.TrimSuffix(o.Kernel.Release, "-default")), nil
|
||||
}
|
||||
|
||||
func (o *suse) scanUpdatablePackages() (models.Packages, error) {
|
||||
cmd := ""
|
||||
if v, _ := o.Distro.MajorVersion(); v < 12 {
|
||||
cmd = "zypper -q lu"
|
||||
} else {
|
||||
cmd = "zypper --no-color -q lu"
|
||||
}
|
||||
r := o.exec(cmd, noSudo)
|
||||
if !r.isSuccess() {
|
||||
return nil, fmt.Errorf("Failed to scan updatable packages: %v", r)
|
||||
}
|
||||
return o.parseZypperLULines(r.Stdout)
|
||||
}
|
||||
|
||||
func (o *suse) parseZypperLULines(stdout string) (models.Packages, error) {
|
||||
updatables := models.Packages{}
|
||||
scanner := bufio.NewScanner(strings.NewReader(stdout))
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if strings.HasPrefix(line, "S | Repository") ||
|
||||
strings.HasPrefix(line, "--+----------------") {
|
||||
continue
|
||||
}
|
||||
pack, err := o.parseZypperLUOneLine(line)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
updatables[pack.Name] = *pack
|
||||
}
|
||||
return updatables, nil
|
||||
}
|
||||
|
||||
func (o *suse) parseZypperLUOneLine(line string) (*models.Package, error) {
|
||||
fs := strings.Fields(line)
|
||||
if len(fs) != 11 {
|
||||
return nil, fmt.Errorf("zypper -q lu Unknown format: %s", line)
|
||||
}
|
||||
available := strings.Split(fs[8], "-")
|
||||
return &models.Package{
|
||||
Name: fs[4],
|
||||
NewVersion: available[0],
|
||||
NewRelease: available[1],
|
||||
Arch: fs[10],
|
||||
}, nil
|
||||
}
|
||||
106
scan/suse_test.go
Normal file
106
scan/suse_test.go
Normal file
@@ -0,0 +1,106 @@
|
||||
/* Vuls - Vulnerability Scanner
|
||||
Copyright (C) 2016 Future Architect, Inc. Japan.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package scan
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/future-architect/vuls/config"
|
||||
"github.com/future-architect/vuls/models"
|
||||
"github.com/k0kubun/pp"
|
||||
)
|
||||
|
||||
func TestScanUpdatablePackages(t *testing.T) {
|
||||
r := newSUSE(config.ServerInfo{})
|
||||
r.Distro = config.Distro{Family: "sles"}
|
||||
stdout := `S | Repository | Name | Current Version | Available Version | Arch
|
||||
--+---------------------------------------------+-------------------------------+-----------------------------+-----------------------------+-------
|
||||
v | SLES12-SP2-Updates | SUSEConnect | 0.3.0-19.8.1 | 0.3.1-19.11.2 | x86_64
|
||||
v | SLES12-SP2-Updates | SuSEfirewall2 | 3.6.312-2.3.1 | 3.6.312-2.10.1 | noarch`
|
||||
|
||||
var tests = []struct {
|
||||
in string
|
||||
out models.Packages
|
||||
}{
|
||||
{
|
||||
stdout,
|
||||
models.NewPackages(
|
||||
models.Package{
|
||||
Name: "SUSEConnect",
|
||||
NewVersion: "0.3.1",
|
||||
NewRelease: "19.11.2",
|
||||
Arch: "x86_64",
|
||||
},
|
||||
models.Package{
|
||||
Name: "SuSEfirewall2",
|
||||
NewVersion: "3.6.312",
|
||||
NewRelease: "2.10.1",
|
||||
Arch: "noarch",
|
||||
},
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
packages, err := r.parseZypperLULines(tt.in)
|
||||
if err != nil {
|
||||
t.Errorf("Error has occurred, err: %s\ntt.in: %v", err, tt.in)
|
||||
return
|
||||
}
|
||||
for name, ePack := range tt.out {
|
||||
if !reflect.DeepEqual(ePack, packages[name]) {
|
||||
e := pp.Sprintf("%v", ePack)
|
||||
a := pp.Sprintf("%v", packages[name])
|
||||
t.Errorf("expected %s, actual %s", e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestScanUpdatablePackage(t *testing.T) {
|
||||
r := newSUSE(config.ServerInfo{})
|
||||
r.Distro = config.Distro{Family: "sles"}
|
||||
stdout := `v | SLES12-SP2-Updates | SUSEConnect | 0.3.0-19.8.1 | 0.3.1-19.11.2 | x86_64`
|
||||
|
||||
var tests = []struct {
|
||||
in string
|
||||
out models.Package
|
||||
}{
|
||||
{
|
||||
stdout,
|
||||
models.Package{
|
||||
Name: "SUSEConnect",
|
||||
NewVersion: "0.3.1",
|
||||
NewRelease: "19.11.2",
|
||||
Arch: "x86_64",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
pack, err := r.parseZypperLUOneLine(tt.in)
|
||||
if err != nil {
|
||||
t.Errorf("Error has occurred, err: %s\ntt.in: %v", err, tt.in)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(*pack, tt.out) {
|
||||
e := pp.Sprintf("%v", tt.out)
|
||||
a := pp.Sprintf("%v", pack)
|
||||
t.Errorf("expected %s, actual %s", e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
69
scan/utils.go
Normal file
69
scan/utils.go
Normal file
@@ -0,0 +1,69 @@
|
||||
/* Vuls - Vulnerability Scanner
|
||||
Copyright (C) 2016 Future Architect, Inc. Japan.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package scan
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/future-architect/vuls/config"
|
||||
"github.com/future-architect/vuls/models"
|
||||
"github.com/future-architect/vuls/util"
|
||||
)
|
||||
|
||||
func isRunningKernel(pack models.Package, family string, kernel models.Kernel) (isKernel, running bool) {
|
||||
switch family {
|
||||
case config.SUSEEnterpriseServer:
|
||||
if pack.Name == "kernel-default" {
|
||||
// Remove the last period and later because uname don't show that.
|
||||
ss := strings.Split(pack.Release, ".")
|
||||
rel := strings.Join(ss[0:len(ss)-1], ".")
|
||||
ver := fmt.Sprintf("%s-%s-default", pack.Version, rel)
|
||||
return true, kernel.Release == ver
|
||||
}
|
||||
return false, false
|
||||
|
||||
case config.RedHat, config.Oracle, config.CentOS, config.Amazon:
|
||||
if pack.Name == "kernel" {
|
||||
ver := fmt.Sprintf("%s-%s.%s", pack.Version, pack.Release, pack.Arch)
|
||||
return true, kernel.Release == ver
|
||||
}
|
||||
return false, false
|
||||
|
||||
default:
|
||||
util.Log.Warnf("Reboot required is not implemented yet: %s, %s", family, kernel)
|
||||
}
|
||||
return false, false
|
||||
}
|
||||
|
||||
func rpmQa(distro config.Distro) string {
|
||||
const old = "rpm -qa --queryformat '%{NAME} %{EPOCH} %{VERSION} %{RELEASE} %{ARCH}\n'"
|
||||
const new = "rpm -qa --queryformat '%{NAME} %{EPOCHNUM} %{VERSION} %{RELEASE} %{ARCH}\n'"
|
||||
switch distro.Family {
|
||||
case config.SUSEEnterpriseServer:
|
||||
if v, _ := distro.MajorVersion(); v < 12 {
|
||||
return old
|
||||
}
|
||||
return new
|
||||
default:
|
||||
if v, _ := distro.MajorVersion(); v < 6 {
|
||||
return old
|
||||
}
|
||||
return new
|
||||
}
|
||||
}
|
||||
117
scan/utils_test.go
Normal file
117
scan/utils_test.go
Normal file
@@ -0,0 +1,117 @@
|
||||
/* Vuls - Vulnerability Scanner
|
||||
Copyright (C) 2016 Future Architect, Inc. Japan.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package scan
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/future-architect/vuls/config"
|
||||
"github.com/future-architect/vuls/models"
|
||||
)
|
||||
|
||||
func TestIsRunningKernelSUSE(t *testing.T) {
|
||||
r := newSUSE(config.ServerInfo{})
|
||||
r.Distro = config.Distro{Family: config.SUSEEnterpriseServer}
|
||||
|
||||
kernel := models.Kernel{
|
||||
Release: "4.4.74-92.35-default",
|
||||
Version: "",
|
||||
}
|
||||
|
||||
var tests = []struct {
|
||||
pack models.Package
|
||||
family string
|
||||
kernel models.Kernel
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
pack: models.Package{
|
||||
Name: "kernel-default",
|
||||
Version: "4.4.74",
|
||||
Release: "92.35.1",
|
||||
Arch: "x86_64",
|
||||
},
|
||||
family: config.SUSEEnterpriseServer,
|
||||
kernel: kernel,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
pack: models.Package{
|
||||
Name: "kernel-default",
|
||||
Version: "4.4.59",
|
||||
Release: "92.20.2",
|
||||
Arch: "x86_64",
|
||||
},
|
||||
family: config.SUSEEnterpriseServer,
|
||||
kernel: kernel,
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
_, actual := isRunningKernel(tt.pack, tt.family, tt.kernel)
|
||||
if tt.expected != actual {
|
||||
t.Errorf("[%d] expected %t, actual %t", i, tt.expected, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsRunningKernelRedHatLikeLinux(t *testing.T) {
|
||||
r := newRedhat(config.ServerInfo{})
|
||||
r.Distro = config.Distro{Family: config.Amazon}
|
||||
|
||||
kernel := models.Kernel{
|
||||
Release: "4.9.43-17.38.amzn1.x86_64",
|
||||
Version: "",
|
||||
}
|
||||
|
||||
var tests = []struct {
|
||||
pack models.Package
|
||||
family string
|
||||
kernel models.Kernel
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
pack: models.Package{
|
||||
Name: "kernel",
|
||||
Version: "4.9.43",
|
||||
Release: "17.38.amzn1",
|
||||
Arch: "x86_64",
|
||||
},
|
||||
family: config.Amazon,
|
||||
kernel: kernel,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
pack: models.Package{
|
||||
Name: "kernel",
|
||||
Version: "4.9.38",
|
||||
Release: "16.35.amzn1",
|
||||
Arch: "x86_64",
|
||||
},
|
||||
family: config.Amazon,
|
||||
kernel: kernel,
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
_, actual := isRunningKernel(tt.pack, tt.family, tt.kernel)
|
||||
if tt.expected != actual {
|
||||
t.Errorf("[%d] expected %t, actual %t", i, tt.expected, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user