-
-
Notifications
You must be signed in to change notification settings - Fork 18
/
handler_mailfrom.go
94 lines (76 loc) · 3.27 KB
/
handler_mailfrom.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
package smtpmock
import "errors"
// MAILFROM command handler
type handlerMailfrom struct {
*handler
}
// MAILFROM command handler builder. Returns pointer to new handlerHelo structure
func newHandlerMailfrom(session sessionInterface, message *Message, configuration *configuration) *handlerMailfrom {
return &handlerMailfrom{&handler{session: session, message: message, configuration: configuration}}
}
// MAILFROM handler methods
// Main MAILFROM handler runner
func (handler *handlerMailfrom) run(request string) {
handler.clearError()
handler.clearMessage()
if handler.isInvalidRequest(request) {
return
}
handler.writeResult(true, request, handler.configuration.msgMailfromReceived)
}
// Erases all message data from MAILFROM command
func (handler *handlerMailfrom) clearMessage() {
messageWithData := handler.message
clearedMessage := &Message{
heloRequest: messageWithData.heloRequest,
heloResponse: messageWithData.heloResponse,
helo: messageWithData.helo,
}
*messageWithData = *clearedMessage
}
// Writes handled HELO result to session, message. Always returns true
func (handler *handlerMailfrom) writeResult(isSuccessful bool, request, response string) bool {
session, message := handler.session, handler.message
if !isSuccessful {
session.addError(errors.New(response))
}
message.mailfromRequest, message.mailfromResponse, message.mailfrom = request, response, isSuccessful
session.writeResponse(response, handler.configuration.responseDelayMailfrom)
return true
}
// Invalid MAILFROM command sequence predicate. Returns true and writes result for case when
// MAILFROM command sequence is invalid (HELO command was failure), otherwise returns false
func (handler *handlerMailfrom) isInvalidCmdSequence(request string) bool {
if !handler.message.helo {
return handler.writeResult(false, request, handler.configuration.msgInvalidCmdMailfromSequence)
}
return false
}
// Invalid MAILFROM command argument predicate. Returns true and writes result for case when
// MAILFROM command argument is invalid, otherwise returns false
func (handler *handlerMailfrom) isInvalidCmdArg(request string) bool {
if !matchRegex(request, validMailfromComplexCmdRegexPattern) {
return handler.writeResult(false, request, handler.configuration.msgInvalidCmdMailfromArg)
}
return false
}
// Returns email from MAILFROM request
func (handler *handlerMailfrom) mailfromEmail(request string) string {
return regexCaptureGroup(request, validMailfromComplexCmdRegexPattern, 2)
}
// Custom behavior for MAILFROM email. Returns true and writes result for case when
// MAILFROM email is included in configuration.blacklistedMailfromEmails slice
func (handler *handlerMailfrom) isBlacklistedEmail(request string) bool {
configuration := handler.configuration
if isIncluded(configuration.blacklistedMailfromEmails, handler.mailfromEmail(request)) {
return handler.writeResult(false, request, configuration.msgMailfromBlacklistedEmail)
}
return false
}
// Invalid MAILFROM command request complex predicate. Returns true for case when one
// of the chain checks returns true, otherwise returns false
func (handler *handlerMailfrom) isInvalidRequest(request string) bool {
return handler.isInvalidCmdSequence(request) ||
handler.isInvalidCmdArg(request) ||
handler.isBlacklistedEmail(request)
}