forked from eaigner/libspf2
/
spf2.go
124 lines (105 loc) · 2.61 KB
/
spf2.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
124
package libspf2
/*
#cgo LDFLAGS: -L/usr/local/lib -L/usr/lib -lspf2
#cgo CFLAGS: -g -O2 -Wno-error -I/usr/include -I/usr/local/include
#include <stdio.h>
#include <netdb.h>
#include <spf2/spf.h>
*/
import "C"
const (
SPFResultINVALID = Result(C.SPF_RESULT_INVALID) // (invalid)
SPFResultPASS = Result(C.SPF_RESULT_PASS) // pass
SPFResultFAIL = Result(C.SPF_RESULT_FAIL) // fail
SPFResultSOFTFAIL = Result(C.SPF_RESULT_SOFTFAIL) // softfail
SPFResultNEUTRAL = Result(C.SPF_RESULT_NEUTRAL) // neutral
SPFResultPERMERROR = Result(C.SPF_RESULT_PERMERROR) // permerror
SPFResultTEMPERROR = Result(C.SPF_RESULT_TEMPERROR) // temperror
SPFResultNONE = Result(C.SPF_RESULT_NONE) // none
)
type Server struct {
s *C.SPF_server_t
}
// NewServer creates a new server
func NewServer() *Server {
srv := new(Server)
srv.s = C.SPF_server_new(C.SPF_DNS_CACHE, 0)
return srv
}
// Free frees the server handle
func (s *Server) Free() {
if s.s != nil {
C.SPF_server_free(s.s)
s.s = nil
}
}
type Request struct {
s *Server
r *C.SPF_request_t
}
// NewRequest creates a new SPF request
func NewRequest(s *Server) *Request {
r := new(Request)
r.s = s
r.r = C.SPF_request_new(s.s)
return r
}
// SetIPv4Addr sets the sender IPv4
func (r *Request) SetIPv4Addr(addr string) error {
var stat C.SPF_errcode_t
stat = C.SPF_request_set_ipv4_str(r.r, C.CString(addr))
if stat != C.SPF_E_SUCCESS {
return &spfError{stat}
}
return nil
}
// SetEnvFrom sets the sender host
func (r *Request) SetEnvFrom(fromHost string) error {
var stat C.int
stat = C.SPF_request_set_env_from(r.r, C.CString(fromHost))
if stat != C.int(C.SPF_E_SUCCESS) {
return &spfError{C.SPF_errcode_t(stat)}
}
return nil
}
// Query starts the SPF query
func (r *Request) Query() (*Response, error) {
var stat C.SPF_errcode_t
var resp *C.SPF_response_t
stat = C.SPF_request_query_mailfrom(r.r, &resp)
if stat != C.SPF_E_SUCCESS {
return nil, &spfError{stat}
}
return &Response{resp}, nil
}
// Free the request handle
func (r *Request) Free() {
if r.r != nil {
C.SPF_request_free(r.r)
r.r = nil
}
}
type Response struct {
r *C.SPF_response_t
}
// Result returns the SPF validation result
func (r *Response) Result() Result {
return Result(C.SPF_response_result(r.r))
}
// Free frees the response handle
func (r *Response) Free() {
if r.r != nil {
C.SPF_response_free(r.r)
r.r = nil
}
}
type Result int
func (r Result) String() string {
return C.GoString(C.SPF_strresult(C.SPF_result_t(r)))
}
type spfError struct {
code C.SPF_errcode_t
}
func (e *spfError) Error() string {
return C.GoString(C.SPF_strerror(e.code))
}