Skip to content

Commit 6a2ca8f

Browse files
committed
check OS
1 parent 5529c83 commit 6a2ca8f

File tree

8 files changed

+352
-4
lines changed

8 files changed

+352
-4
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package amazonlinux
2+
3+
import (
4+
"bufio"
5+
"bytes"
6+
"errors"
7+
"fmt"
8+
"strings"
9+
10+
"github.com/knqyf263/fanal/analyzer/os"
11+
12+
"github.com/knqyf263/fanal/analyzer"
13+
"github.com/knqyf263/fanal/extractor"
14+
)
15+
16+
func init() {
17+
analyzer.RegisterOSAnalyzer(&amazonlinuxOSAnalyzer{})
18+
}
19+
20+
type amazonlinuxOSAnalyzer struct{}
21+
22+
func (a amazonlinuxOSAnalyzer) Analyze(fileMap extractor.FileMap) (analyzer.OS, error) {
23+
for _, filename := range a.RequiredFiles() {
24+
file, ok := fileMap[filename]
25+
if !ok {
26+
continue
27+
}
28+
scanner := bufio.NewScanner(bytes.NewBuffer(file))
29+
for scanner.Scan() {
30+
line := scanner.Text()
31+
fields := strings.Fields(line)
32+
// Amazon Linuxという名称が確認できたときのみ
33+
if strings.HasPrefix(line, "Amazon Linux release 2") {
34+
return analyzer.OS{
35+
Family: os.Amazon,
36+
Name: fmt.Sprintf("%s %s", fields[3], fields[4]),
37+
}, nil
38+
} else if strings.HasPrefix(line, "Amazon Linux") {
39+
return analyzer.OS{
40+
Family: os.Amazon,
41+
Name: strings.Join(fields[2:], " "),
42+
}, nil
43+
}
44+
}
45+
}
46+
return analyzer.OS{}, errors.New("amzn: Not match")
47+
}
48+
49+
func (a amazonlinuxOSAnalyzer) RequiredFiles() []string {
50+
return []string{"etc/system-release"}
51+
}

analyzer/os/const.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package os
2+
3+
const (
4+
// RedHat is done
5+
RedHat = "redhat"
6+
7+
// Debian is done
8+
Debian = "debian"
9+
10+
// Ubuntu is done
11+
Ubuntu = "ubuntu"
12+
13+
// CentOS is done
14+
CentOS = "centos"
15+
16+
// Fedora is done
17+
Fedora = "fedora"
18+
19+
// Amazon is done
20+
Amazon = "amazon"
21+
22+
// Oracle is done
23+
Oracle = "oracle"
24+
25+
// FreeBSD currently doesn't support docker
26+
// FreeBSD = "freebsd"
27+
28+
// Windows only run windows os
29+
// TODO : support windows
30+
Windows = "windows"
31+
32+
// OpenSUSE is done
33+
OpenSUSE = "opensuse"
34+
35+
// OpenSUSELeap is
36+
OpenSUSELeap = "opensuse.leap"
37+
38+
// OpenSUSETumbleweed is done
39+
OpenSUSETumbleweed = "opensuse.tumbleweed"
40+
41+
// Alpine is done
42+
Alpine = "alpine"
43+
)

analyzer/os/debian/debian.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package debian
2+
3+
import (
4+
"bufio"
5+
"bytes"
6+
"errors"
7+
"regexp"
8+
"strings"
9+
10+
"github.com/knqyf263/fanal/analyzer/os"
11+
12+
"github.com/knqyf263/fanal/analyzer"
13+
"github.com/knqyf263/fanal/extractor"
14+
)
15+
16+
func init() {
17+
analyzer.RegisterOSAnalyzer(&debianOSAnalyzer{})
18+
}
19+
20+
type debianOSAnalyzer struct{}
21+
22+
func (a debianOSAnalyzer) Analyze(fileMap extractor.FileMap) (analyzer.OS, error) {
23+
for _, filename := range a.RequiredFiles() {
24+
file, ok := fileMap[filename]
25+
if !ok {
26+
continue
27+
}
28+
scanner := bufio.NewScanner(bytes.NewBuffer(file))
29+
for scanner.Scan() {
30+
line := scanner.Text()
31+
32+
// Ubuntu also exist debian_version, but format is not number
33+
re := regexp.MustCompile(`(\d+).(\d+)`)
34+
if re.MatchString(strings.TrimSpace(line)) {
35+
return analyzer.OS{Family: os.Debian, Name: line}, nil
36+
}
37+
}
38+
}
39+
return analyzer.OS{}, errors.New("debian: Not match")
40+
}
41+
42+
func (a debianOSAnalyzer) RequiredFiles() []string {
43+
return []string{"etc/debian_version"}
44+
}

analyzer/os/opensuse/opensuse.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package opensuse
2+
3+
import (
4+
"bufio"
5+
"bytes"
6+
"errors"
7+
"strings"
8+
9+
"github.com/knqyf263/fanal/analyzer/os"
10+
11+
"github.com/knqyf263/fanal/analyzer"
12+
"github.com/knqyf263/fanal/extractor"
13+
)
14+
15+
func init() {
16+
analyzer.RegisterOSAnalyzer(&opensuseOSAnalyzer{})
17+
}
18+
19+
type opensuseOSAnalyzer struct{}
20+
21+
// TODO : opensuse/tumbleweed, opensuse/leap のimageのときうまくいかないので調査
22+
// そもそも os-release のファイル自体が認識されていない
23+
func (a opensuseOSAnalyzer) Analyze(fileMap extractor.FileMap) (analyzer.OS, error) {
24+
for _, filename := range a.RequiredFiles() {
25+
file, ok := fileMap[filename]
26+
if !ok {
27+
continue
28+
}
29+
suseName := ""
30+
scanner := bufio.NewScanner(bytes.NewBuffer(file))
31+
for scanner.Scan() {
32+
line := scanner.Text()
33+
if strings.HasPrefix(line, "NAME=\"openSUSE") {
34+
if strings.Contains(line, "Leap") {
35+
suseName = os.OpenSUSELeap
36+
} else if strings.Contains(line, "Tumbleweed") {
37+
suseName = os.OpenSUSETumbleweed
38+
} else {
39+
suseName = os.OpenSUSE
40+
}
41+
continue
42+
}
43+
44+
if suseName != "" && strings.HasPrefix(line, "VERSION_ID=") {
45+
return analyzer.OS{
46+
Family: suseName,
47+
Name: strings.TrimSpace(line[12 : len(line)-1]),
48+
}, nil
49+
}
50+
}
51+
}
52+
return analyzer.OS{}, errors.New("opensuse: Not match")
53+
}
54+
55+
func (a opensuseOSAnalyzer) RequiredFiles() []string {
56+
return []string{"etc/os-release"}
57+
}

analyzer/os/redhatbase/redhatbase.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package redhatbase
2+
3+
import (
4+
"bufio"
5+
"bytes"
6+
"errors"
7+
"regexp"
8+
"strings"
9+
10+
"github.com/knqyf263/fanal/analyzer/os"
11+
12+
"github.com/knqyf263/fanal/analyzer"
13+
"github.com/knqyf263/fanal/extractor"
14+
)
15+
16+
func init() {
17+
analyzer.RegisterOSAnalyzer(&redhatOSAnalyzer{})
18+
}
19+
20+
type redhatOSAnalyzer struct{}
21+
22+
var redhatRe = regexp.MustCompile(`(.*) release (\d[\d\.]*)`)
23+
24+
func (a redhatOSAnalyzer) Analyze(fileMap extractor.FileMap) (analyzer.OS, error) {
25+
if file, ok := fileMap["etc/centos-release"]; ok {
26+
scanner := bufio.NewScanner(bytes.NewBuffer(file))
27+
for scanner.Scan() {
28+
line := scanner.Text()
29+
result := redhatRe.FindStringSubmatch(strings.TrimSpace(line))
30+
if len(result) != 3 {
31+
return analyzer.OS{}, errors.New("cent: Invalid centos-release")
32+
}
33+
34+
switch strings.ToLower(result[1]) {
35+
case "centos", "centos linux":
36+
return analyzer.OS{Family: os.CentOS, Name: result[2]}, nil
37+
}
38+
}
39+
}
40+
41+
if file, ok := fileMap["etc/oracle-release"]; ok {
42+
scanner := bufio.NewScanner(bytes.NewBuffer(file))
43+
for scanner.Scan() {
44+
line := scanner.Text()
45+
result := redhatRe.FindStringSubmatch(strings.TrimSpace(line))
46+
if len(result) != 3 {
47+
return analyzer.OS{}, errors.New("oracle: Invalid oracle-release")
48+
}
49+
return analyzer.OS{Family: os.Oracle, Name: result[2]}, nil
50+
}
51+
}
52+
53+
if file, ok := fileMap["etc/fedora-release"]; ok {
54+
scanner := bufio.NewScanner(bytes.NewBuffer(file))
55+
for scanner.Scan() {
56+
line := scanner.Text()
57+
result := redhatRe.FindStringSubmatch(strings.TrimSpace(line))
58+
if len(result) != 3 {
59+
return analyzer.OS{}, errors.New("cent: Invalid fedora-release")
60+
}
61+
62+
switch strings.ToLower(result[1]) {
63+
case "fedora", "fedora linux":
64+
return analyzer.OS{Family: os.Fedora, Name: result[2]}, nil
65+
}
66+
}
67+
}
68+
69+
if file, ok := fileMap["etc/redhat-release"]; ok {
70+
scanner := bufio.NewScanner(bytes.NewBuffer(file))
71+
for scanner.Scan() {
72+
line := scanner.Text()
73+
result := redhatRe.FindStringSubmatch(strings.TrimSpace(line))
74+
if len(result) != 3 {
75+
return analyzer.OS{}, errors.New("redhat: Invalid redhat-release")
76+
}
77+
78+
switch strings.ToLower(result[1]) {
79+
case "centos", "centos linux":
80+
return analyzer.OS{Family: os.CentOS, Name: result[2]}, nil
81+
case "oracle", "oracle linux", "oracle linux server":
82+
return analyzer.OS{Family: os.Oracle, Name: result[2]}, nil
83+
case "fedora", "fedora linux":
84+
return analyzer.OS{Family: os.Fedora, Name: result[2]}, nil
85+
default:
86+
return analyzer.OS{Family: os.RedHat, Name: result[2]}, nil
87+
}
88+
}
89+
}
90+
91+
return analyzer.OS{}, errors.New("redhatbase : Not match")
92+
}
93+
94+
func (a redhatOSAnalyzer) RequiredFiles() []string {
95+
return []string{
96+
"etc/redhat-release",
97+
"etc/oracle-release",
98+
"etc/fedora-release",
99+
"etc/centos-release",
100+
}
101+
}

analyzer/os/ubuntu/ubuntu.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package ubuntu
2+
3+
import (
4+
"bufio"
5+
"bytes"
6+
"errors"
7+
"strings"
8+
9+
"github.com/knqyf263/fanal/analyzer/os"
10+
11+
"github.com/knqyf263/fanal/analyzer"
12+
"github.com/knqyf263/fanal/extractor"
13+
)
14+
15+
func init() {
16+
analyzer.RegisterOSAnalyzer(&ubuntuOSAnalyzer{})
17+
}
18+
19+
type ubuntuOSAnalyzer struct{}
20+
21+
func (a ubuntuOSAnalyzer) Analyze(fileMap extractor.FileMap) (analyzer.OS, error) {
22+
for _, filename := range a.RequiredFiles() {
23+
file, ok := fileMap[filename]
24+
if !ok {
25+
continue
26+
}
27+
isUbuntu := false
28+
scanner := bufio.NewScanner(bytes.NewBuffer(file))
29+
for scanner.Scan() {
30+
line := scanner.Text()
31+
if line == "DISTRIB_ID=Ubuntu" {
32+
isUbuntu = true
33+
continue
34+
}
35+
36+
if isUbuntu && strings.HasPrefix(line, "DISTRIB_RELEASE=") {
37+
return analyzer.OS{
38+
Family: os.Ubuntu,
39+
Name: strings.TrimSpace(line[16:]),
40+
}, nil
41+
}
42+
}
43+
}
44+
return analyzer.OS{}, errors.New("ubuntu: Not match")
45+
}
46+
47+
func (a ubuntuOSAnalyzer) RequiredFiles() []string {
48+
return []string{"etc/lsb-release"}
49+
}

analyzer/pkg/dpkg/dpkg.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bufio"
55
"bytes"
66
"errors"
7-
"fmt"
87
"log"
98
"regexp"
109
"strings"
@@ -33,7 +32,6 @@ func (a debianPkgAnalyzer) Analyze(fileMap extractor.FileMap) (pkgs []analyzer.P
3332
detected := false
3433
for _, filename := range a.RequiredFiles() {
3534
file, ok := fileMap[filename]
36-
fmt.Println(filename)
3735
if !ok {
3836
continue
3937
}
@@ -96,8 +94,6 @@ func (a debianPkgAnalyzer) parseDpkgPkg(scanner *bufio.Scanner) (binPkg *analyze
9694
if line == "" {
9795
break
9896
}
99-
fmt.Println(line)
100-
10197
if strings.HasPrefix(line, "Package: ") {
10298
name = strings.TrimSpace(strings.TrimPrefix(line, "Package: "))
10399
} else if strings.HasPrefix(line, "Source: ") {

cmd/fanal/main.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,14 @@ import (
88

99
"github.com/knqyf263/fanal/analyzer"
1010
_ "github.com/knqyf263/fanal/analyzer/os/alpine"
11+
_ "github.com/knqyf263/fanal/analyzer/os/amazonlinux"
12+
_ "github.com/knqyf263/fanal/analyzer/os/debian"
13+
_ "github.com/knqyf263/fanal/analyzer/os/opensuse"
14+
_ "github.com/knqyf263/fanal/analyzer/os/redhatbase"
15+
_ "github.com/knqyf263/fanal/analyzer/os/ubuntu"
1116
_ "github.com/knqyf263/fanal/analyzer/pkg/apk"
17+
_ "github.com/knqyf263/fanal/analyzer/pkg/dpkg"
18+
_ "github.com/knqyf263/fanal/analyzer/pkg/rpm"
1219
"golang.org/x/crypto/ssh/terminal"
1320
)
1421

0 commit comments

Comments
 (0)