-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
transaction_rcpt_to.go
92 lines (89 loc) · 2.79 KB
/
transaction_rcpt_to.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
package msmtpd
import (
"strings"
"go.opentelemetry.io/otel/attribute"
)
func (t *Transaction) handleRCPT(cmd command) {
if len(cmd.params) != 2 || strings.ToUpper(cmd.params[0]) != "TO" {
t.Hate(missingParameterPenalty)
t.reply(502, "Invalid syntax.")
return
}
if t.dataHandlersCalledProperly {
t.LogWarn("RCPT TO called after DATA accepted")
t.Hate(wrongCommandOrderPenalty)
t.reply(502, "wrong order of commands")
return
}
if t.HeloName == "" {
t.LogDebug("RCPT TO called without HELO/EHLO")
t.Hate(missingParameterPenalty)
t.reply(502, "Please introduce yourself first.")
return
}
if !t.Encrypted && t.server.ForceTLS {
t.LogDebug("RCPT TO called without STARTTLS")
t.Hate(missingParameterPenalty)
t.reply(502, "Please turn on TLS by issuing a STARTTLS command.")
return
}
if t.server.Authenticator != nil && t.Username == "" {
t.LogDebug("RCPT TO called without authentication")
t.Hate(missingParameterPenalty)
t.reply(530, "Authentication Required.")
return
}
if t.MailFrom.Address == "" {
t.LogDebug("RCPT TO called without MAIL FROM")
t.Hate(missingParameterPenalty)
t.reply(502, "It seems you haven't called MAIL FROM in order to explain who sends your message.")
return
}
if len(t.RcptTo) >= t.server.MaxRecipients {
t.LogDebug("Too many recipients")
t.Hate(tooManyRecipientsPenalty)
t.reply(452, "Too many recipients")
return
}
addr, err := parseAddress(cmd.params[1])
if err != nil {
t.Hate(missingParameterPenalty)
t.reply(502, "Malformed e-mail address")
return
}
t.LogDebug("Checking recipient %s by %v RecipientCheckers...",
addr.String(), len(t.server.RecipientCheckers))
for k := range t.server.RecipientCheckers {
err = t.server.RecipientCheckers[k](t, addr)
if err != nil {
t.Hate(unknownRecipientPenalty)
t.error(err)
return
}
}
t.RcptTo = append(t.RcptTo, *addr)
switch len(t.RcptTo) {
case 1:
t.LogInfo("Recipient %s will be 1st one in transaction!", addr)
case 2:
t.LogInfo("Recipient %s will be 2nd one in transaction!", addr)
case 3:
t.LogInfo("Recipient %s will be 3rd one in transaction!", addr)
default:
t.LogInfo("Recipient %s will be %dth one in transaction!", addr, len(t.RcptTo))
}
recipientsAsStrings := make([]string, len(t.RcptTo))
for i := range t.RcptTo {
recipientsAsStrings[i] = t.RcptTo[i].String()
}
t.Span.SetAttributes(attribute.StringSlice("to", recipientsAsStrings))
aliasesAsStrings := make([]string, len(t.Aliases))
for i := range t.Aliases {
aliasesAsStrings[i] = t.Aliases[i].String()
}
t.Span.SetAttributes(attribute.StringSlice("aliases", aliasesAsStrings))
t.reply(250, "It seems i can handle delivery for this recipient, i'll do my best!")
if len(t.RcptTo) == 1 { // too many recipients should not give too many love for transaction
t.Love(commandExecutedProperly)
}
}