forked from getlantern/winfirewall
/
winfirewall_windows.go
123 lines (107 loc) · 3.36 KB
/
winfirewall_windows.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
119
120
121
122
123
package winfirewall
/*
#cgo CFLAGS: -DCINTERFACE -DCOBJMACROS -I. -std=c99
#cgo LDFLAGS: -lole32 -loleaut32 -L. -lhnetcfg
#include "winfirewall.h"
*/
import "C"
import (
"errors"
//"fmt"
"unsafe"
)
// NewFirewallPolicy creates a new instance of a Firewall Policy controller
// The only argument is a boolean that will prompt the user to escalate privileges.
func NewFirewallPolicy(asAdmin bool) (*FirewallPolicy, error) {
var policy unsafe.Pointer
hr := C.windows_firewall_initialize(&policy, cBool(asAdmin))
return &FirewallPolicy{
policy: policy,
asAdmin: asAdmin,
}, hresultToGoError(hr)
}
// Cleanup will deallocate and shutdown the COM interface
func (fw *FirewallPolicy) Cleanup() {
C.windows_firewall_cleanup(fw.policy)
}
// IsOn returns the current state of the Firewall
func (fw *FirewallPolicy) IsOn() (bool, error) {
var isOn C.BOOL
hr := C.windows_firewall_is_on(fw.policy, &isOn)
return C.int(isOn) != 0, hresultToGoError(hr)
}
// On will activate the Firewall (requires a priveleged Firewall Policy)
func (fw *FirewallPolicy) On() error {
if !fw.asAdmin {
return errors.New("Requires elevated privileges")
}
return hresultToGoError(C.windows_firewall_turn_on(fw.policy))
}
// On will activate the Firewall (requires a priveleged Firewall Policy)
func (fw *FirewallPolicy) Off() error {
if !fw.asAdmin {
return errors.New("Requires elevated privileges")
}
return hresultToGoError(C.windows_firewall_turn_off(fw.policy))
}
// SetRule will activate the given rule (requires a priveleged Firewall Policy)
func (fw *FirewallPolicy) SetRule(fwr *FirewallRule) error {
if !fw.asAdmin {
return errors.New("Requires elevated privileges")
}
cFwRule := cFirewallRule(fwr)
defer freeCFw(cFwRule)
return hresultToGoError(C.windows_firewall_rule_set(fw.policy, cFwRule))
}
// RuleExists returns true if an equal rule is found
func (fw *FirewallPolicy) RuleExists(fwr *FirewallRule) (bool, error) {
var isOn C.BOOL
cFwRule := cFirewallRule(fwr)
defer freeCFw(cFwRule)
hr := C.windows_firewall_rule_exists(fw.policy, cFirewallRule(fwr), &isOn)
return C.int(isOn) != 0, hresultToGoError(hr)
}
// RemoveRule removes a rule if an equal one is found (requires a privileged
// Firewall Policy)
func (fw *FirewallPolicy) RemoveRule(fwr *FirewallRule) error {
if !fw.asAdmin {
return errors.New("Requires elevated privileges")
}
cFwRule := cFirewallRule(fwr)
defer freeCFw(cFwRule)
return hresultToGoError(C.windows_firewall_rule_remove(fw.policy, cFwRule))
}
// Helper functions
func cBool(goBool bool) C.BOOL {
if goBool {
return C.BOOL(1)
} else {
return C.BOOL(0)
}
}
func cFirewallRule(goFwRule *FirewallRule) *C.firewall_rule_t {
return &C.firewall_rule_t{
name: C.CString(goFwRule.Name),
description: C.CString(goFwRule.Description),
group: C.CString(goFwRule.Group),
application: C.CString(goFwRule.Application),
port: C.CString(goFwRule.Port),
outbound: cBool(goFwRule.Outbound),
}
}
func freeCFw(fwr *C.firewall_rule_t) {
C.free(unsafe.Pointer(fwr.name))
C.free(unsafe.Pointer(fwr.description))
C.free(unsafe.Pointer(fwr.group))
C.free(unsafe.Pointer(fwr.application))
C.free(unsafe.Pointer(fwr.port))
C.free(unsafe.Pointer(fwr))
}
func hresultToGoError(hr C.HRESULT) error {
if hr == C.S_OK {
return nil
}
cStr := (*C.char)(C.hr_to_string(hr))
defer C.free(unsafe.Pointer(cStr))
return errors.New(C.GoString(cStr))
}