Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 129675c

Browse files
committed
Can open a session and dump some layer info.
Signed-off-by: David Anderson <[email protected]>
1 parent 9c70091 commit 129675c

11 files changed

Lines changed: 2894 additions & 0 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
includes/
2+
test.exe

cmd/test/main.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
6+
"inet.af/winfirewall"
7+
)
8+
9+
func main() {
10+
sess, err := winfirewall.New()
11+
if err != nil {
12+
fmt.Println("fail:", err)
13+
}
14+
defer sess.Close()
15+
fmt.Println("open!")
16+
sess.Test()
17+
}

generate.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package winfirewall
2+
3+
//go:generate go run generators/gen_guids.go includes/fwpmu.h zguids.go
4+
//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go syscall.go

generators/gen_guids.go

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"bytes"
6+
"fmt"
7+
"io"
8+
"io/ioutil"
9+
"os"
10+
"strings"
11+
)
12+
13+
func fatalf(msg string, args ...interface{}) {
14+
fmt.Printf(msg+"\n", args...)
15+
os.Exit(1)
16+
}
17+
18+
var generated []string
19+
20+
func main() {
21+
fwpmuPath, outPath := os.Args[1], os.Args[2]
22+
23+
f, err := os.Open(fwpmuPath)
24+
if err != nil {
25+
fatalf("reading .h: %v", err)
26+
}
27+
defer f.Close()
28+
29+
r := bufio.NewReader(f)
30+
31+
var out bytes.Buffer
32+
out.WriteString(`package winfirewall
33+
34+
import "golang.org/x/sys/windows"
35+
36+
`)
37+
38+
for {
39+
l, err := r.ReadString('\n')
40+
if err == io.EOF {
41+
break
42+
} else if err != nil {
43+
fatalf("reading from .h: %v", err)
44+
}
45+
l = strings.TrimSpace(l)
46+
47+
if !strings.HasPrefix(l, "DEFINE_GUID") {
48+
continue
49+
}
50+
51+
name, g1, g2, g3, g4, err := readGUIDDef(r, l)
52+
if err != nil {
53+
fatalf("reading GUID def: %v", err)
54+
}
55+
56+
fmt.Fprintf(&out, `var %s = windows.GUID{
57+
Data1: %s,
58+
Data2: %s,
59+
Data3: %s,
60+
Data4: [8]byte{%s},
61+
}
62+
63+
`, varName(name), g1, g2, g3, g4)
64+
generated = append(generated, name)
65+
}
66+
67+
out.WriteString("var guidNames = map[windows.GUID]string{\n")
68+
for _, name := range generated {
69+
fmt.Fprintf(&out, "%s: %q,\n", varName(name), name)
70+
}
71+
out.WriteString("}\n")
72+
73+
// bs, err := format.Source(out.Bytes())
74+
// if err != nil {
75+
// fatalf("formatting source code: %v", err)
76+
// }
77+
78+
if err := ioutil.WriteFile(outPath, out.Bytes(), 0644); err != nil {
79+
fatalf("writing generated file: %v", err)
80+
}
81+
}
82+
83+
var keepUpper = []string{
84+
"ALE",
85+
"DCOM",
86+
"EP",
87+
"ICMP",
88+
"ID",
89+
"IKE",
90+
"IP",
91+
"KM",
92+
"LIPS",
93+
"MAC",
94+
"OUI",
95+
"RPC",
96+
"SNAP",
97+
"TCP",
98+
"UDP",
99+
"UM",
100+
"UUID",
101+
"VLAN",
102+
"WFP",
103+
}
104+
var replacements = map[string]string{
105+
"IPSEC": "IPSec",
106+
"IKEV2": "IKEv2",
107+
"AUTHIP": "AuthIP",
108+
"IPPACKET": "IPPacket",
109+
"IPFORWARD": "IPForward",
110+
"IKEEXT": "IKEExt",
111+
"EPMAP": "EPMap",
112+
}
113+
114+
func varName(guidName string) string {
115+
fs := strings.Split(guidName, "_")
116+
fs[0] = "guid"
117+
remapLoop:
118+
for i, f := range fs[1:] {
119+
for _, k := range keepUpper {
120+
if k == f {
121+
continue remapLoop
122+
}
123+
}
124+
if rep, ok := replacements[f]; ok {
125+
fs[i+1] = rep
126+
} else {
127+
fs[i+1] = strings.Title(strings.ToLower(f))
128+
}
129+
}
130+
131+
return strings.Join(fs, "")
132+
}
133+
134+
func guidType(name string) string {
135+
fs := strings.Split(name, "_")
136+
return fs[1]
137+
}
138+
139+
func readGUIDDef(r *bufio.Reader, l string) (name, g1, g2, g3, g4 string, err error) {
140+
clean := func(s string) string {
141+
s = strings.TrimSpace(s)
142+
return strings.TrimSuffix(s, ",")
143+
}
144+
145+
if strings.HasPrefix(l, "DEFINE_GUID(FWPM_") {
146+
name = strings.Split(l, "(")[1]
147+
} else {
148+
name, err = r.ReadString('\n')
149+
if err != nil {
150+
return
151+
}
152+
}
153+
name = clean(name)
154+
155+
g1, err = r.ReadString('\n')
156+
if err != nil {
157+
return
158+
}
159+
g1 = clean(g1)
160+
161+
g2, err = r.ReadString('\n')
162+
if err != nil {
163+
return
164+
}
165+
g2 = clean(g2)
166+
167+
g3, err = r.ReadString('\n')
168+
if err != nil {
169+
return
170+
}
171+
g3 = clean(g3)
172+
173+
g4, err = r.ReadString('\n')
174+
if err != nil {
175+
return
176+
}
177+
g4 = clean(g4)
178+
179+
return
180+
}

go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module inet.af/winfirewall
2+
3+
go 1.15
4+
5+
require golang.org/x/sys v0.0.0-20210227040730-b0d1d43c014d

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
golang.org/x/sys v0.0.0-20210227040730-b0d1d43c014d h1:9fH9JvLNoSpsDWcXJ4dSE3lZW99Z3OCUZLr07g60U6o=
2+
golang.org/x/sys v0.0.0-20210227040730-b0d1d43c014d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

session.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package winfirewall
2+
3+
import (
4+
"fmt"
5+
"reflect"
6+
"unsafe"
7+
8+
"golang.org/x/sys/windows"
9+
)
10+
11+
type Session struct {
12+
handle windows.Handle
13+
}
14+
15+
func New() (*Session, error) {
16+
session := fwpmSession0{
17+
DisplayData: fwpmDisplayData0{
18+
Name: windows.StringToUTF16Ptr("test"),
19+
Description: windows.StringToUTF16Ptr("test description"),
20+
},
21+
Flags: fwpmSession0FlagDynamic,
22+
TxnWaitTimeoutMillis: windows.INFINITE,
23+
}
24+
25+
var handle windows.Handle
26+
27+
err := fwpmEngineOpen0(nil, authnServiceWinNT, nil, &session, &handle)
28+
if err != nil {
29+
return nil, err
30+
}
31+
32+
return &Session{
33+
handle: handle,
34+
}, nil
35+
}
36+
37+
func (s *Session) Close() error {
38+
if s.handle == 0 {
39+
return nil
40+
}
41+
return fwpmEngineClose0(s.handle)
42+
}
43+
44+
func (s *Session) Test() error {
45+
var enumHandle windows.Handle
46+
if err := fwpmLayerCreateEnumHandle0(s.handle, nil, &enumHandle); err != nil {
47+
return err
48+
}
49+
defer fwpmLayerDestroyEnumHandle0(s.handle, enumHandle)
50+
51+
var layersArray **fwpmLayer0
52+
var numLayers uint32
53+
if err := fwpmLayerEnum0(s.handle, enumHandle, 1000, &layersArray, &numLayers); err != nil {
54+
return err
55+
}
56+
defer fwpmFreeMemory0((**uintptr)(unsafe.Pointer(layersArray)))
57+
58+
var layers []*fwpmLayer0
59+
sh := (*reflect.SliceHeader)(unsafe.Pointer(&layers))
60+
sh.Cap = int(numLayers)
61+
sh.Len = int(numLayers)
62+
sh.Data = uintptr(unsafe.Pointer(layersArray))
63+
64+
for i, layer := range layers {
65+
fmt.Printf("%d\n%#v\n%s\n%s\n%s\n%s\n\n", i, *layer, guidNames[layer.LayerKey], guidNames[layer.DefaultSubLayerKey], windows.UTF16PtrToString(layer.DisplayData.Name), windows.UTF16PtrToString(layer.DisplayData.Name))
66+
}
67+
68+
return nil
69+
}

syscall.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package winfirewall
2+
3+
//sys fwpmEngineOpen0(mustBeNil *uint16, authnService authnService, authIdentity *uintptr, session *fwpmSession0, engineHandle *windows.Handle) (err error) [failretval!=0] = fwpuclnt.FwpmEngineOpen0
4+
5+
//sys fwpmEngineClose0(engineHandle windows.Handle) (err error) [failretval!=0] = fwpuclnt.FwpmEngineClose0
6+
7+
//sys fwpmLayerCreateEnumHandle0(engineHandle windows.Handle, enumTemplate *fwpmLayerEnumTemplate0, handle *windows.Handle) (err error) [failretval!=0] = fwpuclnt.FwpmLayerCreateEnumHandle0
8+
9+
//sys fwpmLayerDestroyEnumHandle0(engineHandle windows.Handle, enumHandle windows.Handle) (err error) [failretval!=0] = fwpuclnt.FwpmLayerDestroyEnumHandle0
10+
11+
//sys fwpmLayerEnum0(engineHandle windows.Handle, enumHandle windows.Handle, numEntriesRequested uint32, entries ***fwpmLayer0, numEntriesReturned *uint32) (err error) [failretval!=0] = fwpuclnt.FwpmLayerEnum0
12+
13+
//sys fwpmFreeMemory0(p **uintptr) = fwpuclnt.FwpmFreeMemory0

types.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package winfirewall
2+
3+
import (
4+
"golang.org/x/sys/windows"
5+
)
6+
7+
type fwpmDisplayData0 struct {
8+
Name *uint16
9+
Description *uint16
10+
}
11+
12+
type fwpmSession0Flags uint32
13+
14+
const fwpmSession0FlagDynamic = 1
15+
16+
type fwpmSession0 struct {
17+
SessionKey windows.GUID
18+
DisplayData fwpmDisplayData0
19+
Flags fwpmSession0Flags
20+
TxnWaitTimeoutMillis uint32
21+
ProcessID uint32
22+
SID *windows.SID
23+
Username *uint16
24+
KernelMode uint8
25+
}
26+
27+
type authnService uint32
28+
29+
const (
30+
authnServiceWinNT authnService = 0xa
31+
authnServiceDefault authnService = 0xffffffff
32+
)
33+
34+
type fwpmLayerEnumTemplate0 struct {
35+
reserved uint64
36+
}
37+
38+
type fwpmLayer0 struct {
39+
LayerKey windows.GUID
40+
DisplayData fwpmDisplayData0
41+
Flags uint32
42+
NumFields uint32
43+
Field *fwpmField0
44+
DefaultSubLayerKey windows.GUID
45+
LayerID uint16
46+
}
47+
48+
type fwpmField0 struct {
49+
FieldKey *windows.GUID
50+
Type fwpmFieldType
51+
DataType fwpmDataType
52+
}
53+
54+
type fwpmFieldType uint32
55+
56+
const (
57+
fwpmFieldTypeRawData fwpmFieldType = iota
58+
fwpmFieldTypeIPAddress
59+
fwpmFieldTypeFlags
60+
)
61+
62+
type fwpmDataType uint32
63+
64+
const (
65+
fwpmDataTypeEmpty fwpmDataType = iota
66+
fwpmDataTypeUint8
67+
fwpmDataTypeUint6
68+
fwpmDataTypeUint2
69+
fwpmDataTypeUint64
70+
fwpmDataTypeInt8
71+
fwpmDataTypeInt16
72+
fwpmDataTypeInt32
73+
fwpmDataTypeInt64
74+
fwpmDataTypeFloat
75+
fwpmDataTypeDouble
76+
fwpmDataTypeByteArray16
77+
fwpmDataTypeByteBlob
78+
fwpmDataTypeSID
79+
fwpmDataTypeSecurityDescriptor
80+
fwpmDataTypeTokenInformation
81+
fwpmDataTypeTokenAccessInformation
82+
fwpmDataTypeUnicodeString
83+
fwpmDataTypeV4AddrMask = 0x100 + iota
84+
fwpmDataTypeV6AddrMask
85+
fwpmDataTypeRange
86+
)

0 commit comments

Comments
 (0)