-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcheck.go
118 lines (106 loc) · 2.28 KB
/
check.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package main
import (
"archive/zip"
"bufio"
"bytes"
"compress/gzip"
"fmt"
"io"
"os"
"strings"
"github.com/h2non/filetype"
"github.com/h2non/filetype/matchers"
)
// type for XML DMARC report
var dmarcType = filetype.NewType("dmarc", "application/dmarc")
func dmarcMatcher(data []byte) bool {
buffer := bytes.NewBuffer(data)
scanner := bufio.NewScanner(buffer)
// skip first line (xml type)
if !scanner.Scan() {
return false
}
if scanner.Scan() {
line := scanner.Text()
if strings.HasPrefix(line, "<feedback>") {
return true
}
}
return false
}
func init() {
// Register the new matcher and its type
filetype.AddMatcher(dmarcType, dmarcMatcher)
}
func checkFile(path string) ([]byte, error) {
header := make([]byte, 128)
var reader io.Reader
file, err := os.Open(path)
if err != nil {
return nil, err
}
t, err := filetype.MatchFile(path)
if err != nil {
return nil, err
}
switch t {
case matchers.TypeGz:
// gzip archive case
gzipReader, err := gzip.NewReader(file)
if err != nil {
return nil, err
}
if _, err := gzipReader.Read(header); err != nil {
return nil, err
}
gzipReader.Close()
// reopen that file
file.Seek(0, 0)
reader, _ = gzip.NewReader(file)
case matchers.TypeZip:
// zip archive case
zipReader, err := zip.OpenReader(path)
if err != nil {
return nil, err
}
defer zipReader.Close()
n := len(zipReader.File)
if n != 1 {
return nil, fmt.Errorf("the zip archive has not a single file (%d)", n)
}
fileReader, err := zipReader.File[0].Open()
if err != nil {
return nil, err
}
// just read that header
if _, err := fileReader.Read(header); err != nil {
return nil, err
}
fileReader.Close()
// reopen the reader
reader, _ = zipReader.File[0].Open()
default:
// assume raw case
file.Seek(0, 0)
if _, err := file.Read(header); err != nil {
return nil, err
}
// reset the reader
file.Seek(0, 0)
reader = file
}
if filetype.IsType(header, dmarcType) {
var buffer bytes.Buffer
if _, err := io.Copy(&buffer, reader); err != nil {
return nil, err
} else {
return buffer.Bytes(), nil
}
// if bytes, err := ioutil.ReadAll(reader); err != nil {
// return nil, err
// } else {
// return bytes, nil
// }
}
return nil, fmt.Errorf("the file is not a DMARC report")
}