mirror of
https://blitiri.com.ar/repos/chasquid
synced 2025-12-17 14:37:02 +00:00
Support submission (directly) over TLS (submissions/smtps/port 465)
This patch adds support for TLS-wrapped submission connections. Instead of clients establishing a connection over plain text and then using STARTTLS to switch over a TLS connection, this new mode allows the clients to connect directly over TLS, like it's done in HTTPS. This is not an official standard yet, but it's reasonably common in practice, and provides some advantages over the traditional submission port. The default port is 465, commonly used for this; chasquid defaults to systemd file descriptor passing as for the other protocols (for now).
This commit is contained in:
@@ -161,6 +161,8 @@ func main() {
|
||||
systemdLs["smtp"], smtpsrv.ModeSMTP)
|
||||
loadAddresses(s, conf.SubmissionAddress,
|
||||
systemdLs["submission"], smtpsrv.ModeSubmission)
|
||||
loadAddresses(s, conf.SubmissionOverTlsAddress,
|
||||
systemdLs["submission_tls"], smtpsrv.ModeSubmissionTLS)
|
||||
|
||||
s.ListenAndServe()
|
||||
}
|
||||
|
||||
11
etc/systemd/system/chasquid-submission_tls.socket
Normal file
11
etc/systemd/system/chasquid-submission_tls.socket
Normal file
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=chasquid mail daemon (submission over TLS sockets)
|
||||
|
||||
[Socket]
|
||||
ListenStream=465
|
||||
FileDescriptorName=submission_tls
|
||||
Service=chasquid.service
|
||||
|
||||
[Install]
|
||||
WantedBy=chasquid.target
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
[Unit]
|
||||
Description=chasquid mail daemon (service)
|
||||
Requires=chasquid-smtp.socket chasquid-submission.socket
|
||||
Requires=chasquid-smtp.socket \
|
||||
chasquid-submission.socket \
|
||||
chasquid-submission_tls.socket
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/local/bin/chasquid \
|
||||
|
||||
@@ -50,6 +50,9 @@ func Load(path string) (*Config, error) {
|
||||
if len(c.SubmissionAddress) == 0 {
|
||||
c.SubmissionAddress = append(c.SubmissionAddress, "systemd")
|
||||
}
|
||||
if len(c.SubmissionOverTlsAddress) == 0 {
|
||||
c.SubmissionOverTlsAddress = append(c.SubmissionOverTlsAddress, "systemd")
|
||||
}
|
||||
|
||||
if c.MailDeliveryAgentBin == "" {
|
||||
c.MailDeliveryAgentBin = "maildrop"
|
||||
|
||||
@@ -44,16 +44,20 @@ type Config struct {
|
||||
// Default: "systemd", which means systemd passes sockets to us.
|
||||
// systemd sockets must be named with "FileDescriptorName=submission".
|
||||
SubmissionAddress []string `protobuf:"bytes,4,rep,name=submission_address,json=submissionAddress" json:"submission_address,omitempty"`
|
||||
// Addresses to listen on for submission-over-TLS (usually port 465).
|
||||
// Default: "systemd", which means systemd passes sockets to us.
|
||||
// systemd sockets must be named with "FileDescriptorName=submission_tls".
|
||||
SubmissionOverTlsAddress []string `protobuf:"bytes,5,rep,name=submission_over_tls_address,json=submissionOverTlsAddress" json:"submission_over_tls_address,omitempty"`
|
||||
// Address for the monitoring http server.
|
||||
// Do NOT expose this to the public internet.
|
||||
// Default: no monitoring http server.
|
||||
MonitoringAddress string `protobuf:"bytes,5,opt,name=monitoring_address,json=monitoringAddress" json:"monitoring_address,omitempty"`
|
||||
MonitoringAddress string `protobuf:"bytes,6,opt,name=monitoring_address,json=monitoringAddress" json:"monitoring_address,omitempty"`
|
||||
// Mail delivery agent (MDA, also known as LDA) to use.
|
||||
// This should point to the binary to use to deliver email to local users.
|
||||
// The content of the email will be passed via stdin.
|
||||
// If it exits unsuccessfully, we assume the mail was not delivered.
|
||||
// Default: "maildrop".
|
||||
MailDeliveryAgentBin string `protobuf:"bytes,6,opt,name=mail_delivery_agent_bin,json=mailDeliveryAgentBin" json:"mail_delivery_agent_bin,omitempty"`
|
||||
MailDeliveryAgentBin string `protobuf:"bytes,7,opt,name=mail_delivery_agent_bin,json=mailDeliveryAgentBin" json:"mail_delivery_agent_bin,omitempty"`
|
||||
// Command line arguments for the mail delivery agent. One per argument.
|
||||
// Some replacements will be done.
|
||||
// On an email sent from marsnik@mars to venera@venus:
|
||||
@@ -66,26 +70,26 @@ type Config struct {
|
||||
//
|
||||
// Default: "-f", "%from%", "-d", "%to_user%" (adequate for procmail
|
||||
// and maildrop).
|
||||
MailDeliveryAgentArgs []string `protobuf:"bytes,7,rep,name=mail_delivery_agent_args,json=mailDeliveryAgentArgs" json:"mail_delivery_agent_args,omitempty"`
|
||||
MailDeliveryAgentArgs []string `protobuf:"bytes,8,rep,name=mail_delivery_agent_args,json=mailDeliveryAgentArgs" json:"mail_delivery_agent_args,omitempty"`
|
||||
// Directory where we store our persistent data.
|
||||
// Default: "/var/lib/chasquid"
|
||||
DataDir string `protobuf:"bytes,8,opt,name=data_dir,json=dataDir" json:"data_dir,omitempty"`
|
||||
DataDir string `protobuf:"bytes,9,opt,name=data_dir,json=dataDir" json:"data_dir,omitempty"`
|
||||
// Suffix separator, to perform suffix removal of local users.
|
||||
// For example, if you set this to "-+", email to local user
|
||||
// "user-blah" and "user+blah" will be delivered to "user".
|
||||
// Including "+" is strongly encouraged, as it is assumed for email
|
||||
// forwarding.
|
||||
// Default: "+".
|
||||
SuffixSeparators string `protobuf:"bytes,9,opt,name=suffix_separators,json=suffixSeparators" json:"suffix_separators,omitempty"`
|
||||
SuffixSeparators string `protobuf:"bytes,10,opt,name=suffix_separators,json=suffixSeparators" json:"suffix_separators,omitempty"`
|
||||
// Characters to drop from the user part on local emails.
|
||||
// For example, if you set this to "._", email to local user
|
||||
// "u.se_r" will be delivered to "user".
|
||||
// Default: ".".
|
||||
DropCharacters string `protobuf:"bytes,10,opt,name=drop_characters,json=dropCharacters" json:"drop_characters,omitempty"`
|
||||
DropCharacters string `protobuf:"bytes,11,opt,name=drop_characters,json=dropCharacters" json:"drop_characters,omitempty"`
|
||||
// Path where to write the mail log to.
|
||||
// If "<syslog>", log using the syslog (at MAIL|INFO priority).
|
||||
// Default: <syslog>
|
||||
MailLogPath string `protobuf:"bytes,11,opt,name=mail_log_path,json=mailLogPath" json:"mail_log_path,omitempty"`
|
||||
MailLogPath string `protobuf:"bytes,12,opt,name=mail_log_path,json=mailLogPath" json:"mail_log_path,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Config) Reset() { *m = Config{} }
|
||||
@@ -100,25 +104,27 @@ func init() {
|
||||
func init() { proto.RegisterFile("config.proto", fileDescriptor0) }
|
||||
|
||||
var fileDescriptor0 = []byte{
|
||||
// 320 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x6c, 0x91, 0xcd, 0x4e, 0x02, 0x31,
|
||||
0x10, 0x80, 0x83, 0xab, 0xfc, 0x14, 0x50, 0x68, 0x34, 0x56, 0x4f, 0xc8, 0x05, 0x12, 0xa3, 0x17,
|
||||
0x63, 0x3c, 0x23, 0x1c, 0x35, 0x31, 0xf0, 0x00, 0xcd, 0x2c, 0x5b, 0xba, 0x93, 0xd0, 0x76, 0xd3,
|
||||
0x29, 0x06, 0x79, 0x4d, 0x5f, 0xc8, 0x6c, 0xd1, 0xc5, 0x44, 0x8f, 0xf3, 0x7d, 0xdf, 0x64, 0x27,
|
||||
0x5b, 0xd6, 0x59, 0x3a, 0xbb, 0x42, 0x7d, 0x5f, 0x78, 0x17, 0xdc, 0xf0, 0x33, 0x61, 0xf5, 0x69,
|
||||
0x04, 0xfc, 0x9a, 0x35, 0x73, 0x47, 0xc1, 0x82, 0x51, 0xa2, 0x36, 0xa8, 0x8d, 0x5b, 0xf3, 0x6a,
|
||||
0xe6, 0x23, 0xd6, 0x33, 0xb0, 0x95, 0x19, 0x04, 0x90, 0x84, 0x3b, 0x25, 0x4d, 0x2a, 0x8e, 0x06,
|
||||
0xb5, 0x71, 0x32, 0xef, 0x1a, 0xd8, 0xce, 0x20, 0xc0, 0x02, 0x77, 0xea, 0x35, 0xe5, 0x37, 0xac,
|
||||
0x43, 0x26, 0x14, 0x12, 0xb2, 0xcc, 0x2b, 0x22, 0x91, 0x0c, 0x92, 0x71, 0x6b, 0xde, 0x2e, 0xd9,
|
||||
0x64, 0x8f, 0xf8, 0x1d, 0xe3, 0xb4, 0x49, 0x0d, 0x12, 0xa1, 0xb3, 0x55, 0x78, 0x1c, 0xc3, 0xfe,
|
||||
0xc1, 0xfc, 0xca, 0x8d, 0xb3, 0x18, 0x9c, 0x47, 0xab, 0xab, 0xfc, 0x24, 0x1e, 0xd8, 0x3f, 0x98,
|
||||
0x9f, 0xfc, 0x91, 0x5d, 0x1a, 0xc0, 0xb5, 0xcc, 0xd4, 0x1a, 0xdf, 0x95, 0xff, 0x90, 0xa0, 0x95,
|
||||
0x0d, 0x32, 0x45, 0x2b, 0xea, 0x71, 0xe7, 0xbc, 0xd4, 0xb3, 0x6f, 0x3b, 0x29, 0xe5, 0x33, 0x5a,
|
||||
0xfe, 0xc4, 0xc4, 0x7f, 0x6b, 0xe0, 0x35, 0x89, 0x46, 0x3c, 0xed, 0xe2, 0xcf, 0xde, 0xc4, 0x6b,
|
||||
0xe2, 0x57, 0xac, 0x19, 0xff, 0x4a, 0x86, 0x5e, 0x34, 0xe3, 0x07, 0x1a, 0xe5, 0x3c, 0x43, 0xcf,
|
||||
0x6f, 0x59, 0x9f, 0x36, 0xab, 0x15, 0x6e, 0x25, 0xa9, 0x02, 0x3c, 0x04, 0xe7, 0x49, 0xb4, 0x62,
|
||||
0xd3, 0xdb, 0x8b, 0x45, 0xc5, 0xf9, 0x88, 0x9d, 0x65, 0xde, 0x15, 0x72, 0x99, 0x83, 0x87, 0x65,
|
||||
0x50, 0x9e, 0x04, 0x8b, 0xe9, 0x69, 0x89, 0xa7, 0x15, 0xe5, 0x43, 0xd6, 0x8d, 0x97, 0xae, 0x9d,
|
||||
0x96, 0x05, 0x84, 0x5c, 0xb4, 0x63, 0xd6, 0x2e, 0xe1, 0x8b, 0xd3, 0x6f, 0x10, 0xf2, 0xb4, 0x1e,
|
||||
0x1f, 0xf7, 0xe1, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x04, 0x0f, 0xa4, 0xff, 0xec, 0x01, 0x00, 0x00,
|
||||
// 351 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x6c, 0x92, 0x4d, 0x4f, 0x22, 0x41,
|
||||
0x10, 0x86, 0xc3, 0xc2, 0xf2, 0xd1, 0xc0, 0x2e, 0x74, 0x76, 0xb3, 0xbd, 0x7a, 0x41, 0x2e, 0x90,
|
||||
0x18, 0xbd, 0x18, 0xe3, 0xc9, 0x03, 0xc2, 0x51, 0xa3, 0x01, 0xef, 0x9d, 0x1a, 0xa6, 0x99, 0xe9,
|
||||
0x64, 0xba, 0x7b, 0x52, 0xd5, 0x10, 0xe4, 0x67, 0xf8, 0x8b, 0xcd, 0x34, 0x32, 0x90, 0xe8, 0xb1,
|
||||
0x9e, 0xf7, 0x79, 0x53, 0x35, 0x93, 0x66, 0x9d, 0xa5, 0xb3, 0x2b, 0x9d, 0x5c, 0xe7, 0xe8, 0xbc,
|
||||
0x1b, 0xbe, 0xd7, 0x58, 0x7d, 0x1a, 0x00, 0x3f, 0x63, 0xcd, 0xd4, 0x91, 0xb7, 0x60, 0x94, 0xa8,
|
||||
0x0c, 0x2a, 0xe3, 0xd6, 0xbc, 0x9c, 0xf9, 0x88, 0xf5, 0x0c, 0x6c, 0x65, 0x0c, 0x1e, 0x24, 0xe9,
|
||||
0x9d, 0x92, 0x26, 0x12, 0x3f, 0x06, 0x95, 0x71, 0x75, 0xde, 0x35, 0xb0, 0x9d, 0x81, 0x87, 0x85,
|
||||
0xde, 0xa9, 0xa7, 0x88, 0x5f, 0xb0, 0x0e, 0x19, 0x9f, 0x4b, 0x88, 0x63, 0x54, 0x44, 0xa2, 0x3a,
|
||||
0xa8, 0x8e, 0x5b, 0xf3, 0x76, 0xc1, 0x26, 0x7b, 0xc4, 0xaf, 0x18, 0xa7, 0x75, 0x64, 0x34, 0x91,
|
||||
0x76, 0xb6, 0x14, 0x6b, 0x41, 0xec, 0x1f, 0x93, 0x83, 0x7e, 0xcf, 0xce, 0x4f, 0x74, 0xb7, 0x51,
|
||||
0x28, 0x7d, 0x46, 0x65, 0xef, 0x67, 0xe8, 0x89, 0xa3, 0xf2, 0xbc, 0x51, 0xf8, 0x9a, 0xd1, 0xc9,
|
||||
0x36, 0xe3, 0xac, 0xf6, 0x0e, 0xb5, 0x4d, 0xca, 0x56, 0x3d, 0x7c, 0x5f, 0xff, 0x98, 0x1c, 0xf4,
|
||||
0x5b, 0xf6, 0xcf, 0x80, 0xce, 0x64, 0xac, 0x32, 0xbd, 0x51, 0xf8, 0x26, 0x21, 0x51, 0xd6, 0xcb,
|
||||
0x48, 0x5b, 0xd1, 0x08, 0x9d, 0x3f, 0x45, 0x3c, 0xfb, 0x4c, 0x27, 0x45, 0xf8, 0xa0, 0x2d, 0xbf,
|
||||
0x63, 0xe2, 0xbb, 0x1a, 0x60, 0x42, 0xa2, 0x19, 0x2e, 0xfc, 0xfb, 0xa5, 0x37, 0xc1, 0x84, 0xf8,
|
||||
0x7f, 0xd6, 0x0c, 0x3f, 0x35, 0xd6, 0x28, 0x5a, 0x61, 0x41, 0xa3, 0x98, 0x67, 0x1a, 0xf9, 0x25,
|
||||
0xeb, 0xd3, 0x7a, 0xb5, 0xd2, 0x5b, 0x49, 0x2a, 0x07, 0x04, 0xef, 0x90, 0x04, 0x0b, 0x4e, 0x6f,
|
||||
0x1f, 0x2c, 0x4a, 0xce, 0x47, 0xec, 0x77, 0x8c, 0x2e, 0x97, 0xcb, 0x14, 0x10, 0x96, 0x5e, 0x21,
|
||||
0x89, 0x76, 0x50, 0x7f, 0x15, 0x78, 0x5a, 0x52, 0x3e, 0x64, 0xdd, 0x70, 0x69, 0xe6, 0x12, 0x99,
|
||||
0x83, 0x4f, 0x45, 0x27, 0x68, 0xed, 0x02, 0x3e, 0xba, 0xe4, 0x05, 0x7c, 0x1a, 0xd5, 0xc3, 0xdb,
|
||||
0xb8, 0xf9, 0x08, 0x00, 0x00, 0xff, 0xff, 0xfb, 0x6f, 0x6c, 0xff, 0x2b, 0x02, 0x00, 0x00,
|
||||
}
|
||||
|
||||
@@ -21,17 +21,22 @@ message Config {
|
||||
// systemd sockets must be named with "FileDescriptorName=submission".
|
||||
repeated string submission_address = 4;
|
||||
|
||||
// Addresses to listen on for submission-over-TLS (usually port 465).
|
||||
// Default: "systemd", which means systemd passes sockets to us.
|
||||
// systemd sockets must be named with "FileDescriptorName=submission_tls".
|
||||
repeated string submission_over_tls_address = 5;
|
||||
|
||||
// Address for the monitoring http server.
|
||||
// Do NOT expose this to the public internet.
|
||||
// Default: no monitoring http server.
|
||||
string monitoring_address = 5;
|
||||
string monitoring_address = 6;
|
||||
|
||||
// Mail delivery agent (MDA, also known as LDA) to use.
|
||||
// This should point to the binary to use to deliver email to local users.
|
||||
// The content of the email will be passed via stdin.
|
||||
// If it exits unsuccessfully, we assume the mail was not delivered.
|
||||
// Default: "maildrop".
|
||||
string mail_delivery_agent_bin = 6;
|
||||
string mail_delivery_agent_bin = 7;
|
||||
|
||||
// Command line arguments for the mail delivery agent. One per argument.
|
||||
// Some replacements will be done.
|
||||
@@ -45,11 +50,11 @@ message Config {
|
||||
//
|
||||
// Default: "-f", "%from%", "-d", "%to_user%" (adequate for procmail
|
||||
// and maildrop).
|
||||
repeated string mail_delivery_agent_args = 7;
|
||||
repeated string mail_delivery_agent_args = 8;
|
||||
|
||||
// Directory where we store our persistent data.
|
||||
// Default: "/var/lib/chasquid"
|
||||
string data_dir = 8;
|
||||
string data_dir = 9;
|
||||
|
||||
// Suffix separator, to perform suffix removal of local users.
|
||||
// For example, if you set this to "-+", email to local user
|
||||
@@ -57,17 +62,17 @@ message Config {
|
||||
// Including "+" is strongly encouraged, as it is assumed for email
|
||||
// forwarding.
|
||||
// Default: "+".
|
||||
string suffix_separators = 9;
|
||||
string suffix_separators = 10;
|
||||
|
||||
// Characters to drop from the user part on local emails.
|
||||
// For example, if you set this to "._", email to local user
|
||||
// "u.se_r" will be delivered to "user".
|
||||
// Default: ".".
|
||||
string drop_characters = 10;
|
||||
string drop_characters = 11;
|
||||
|
||||
// Path where to write the mail log to.
|
||||
// If "<syslog>", log using the syslog (at MAIL|INFO priority).
|
||||
// Default: <syslog>
|
||||
string mail_log_path = 11;
|
||||
string mail_log_path = 12;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,12 +55,31 @@ var (
|
||||
|
||||
// Mode for a socket (listening or connection).
|
||||
// We keep them distinct, as policies can differ between them.
|
||||
type SocketMode string
|
||||
type SocketMode struct {
|
||||
// Is this mode submission?
|
||||
IsSubmission bool
|
||||
|
||||
// Is this mode TLS-wrapped? That means that we don't use STARTTLS, the
|
||||
// connection is directly established over TLS (like HTTPS).
|
||||
TLS bool
|
||||
}
|
||||
|
||||
func (mode SocketMode) String() string {
|
||||
s := "SMTP"
|
||||
if mode.IsSubmission {
|
||||
s = "submission"
|
||||
}
|
||||
if mode.TLS {
|
||||
s += "+TLS"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Valid socket modes.
|
||||
const (
|
||||
ModeSMTP SocketMode = "SMTP"
|
||||
ModeSubmission SocketMode = "submission"
|
||||
var (
|
||||
ModeSMTP = SocketMode{IsSubmission: false, TLS: false}
|
||||
ModeSubmission = SocketMode{IsSubmission: true, TLS: false}
|
||||
ModeSubmissionTLS = SocketMode{IsSubmission: true, TLS: true}
|
||||
)
|
||||
|
||||
// Incoming SMTP connection.
|
||||
@@ -137,6 +156,7 @@ func (c *Conn) Handle() {
|
||||
|
||||
c.tr = trace.New("SMTP.Conn", c.conn.RemoteAddr().String())
|
||||
defer c.tr.Finish()
|
||||
c.tr.Debugf("Connected, mode: %s", c.mode)
|
||||
|
||||
c.tc.PrintfLine("220 %s ESMTP chasquid", c.hostname)
|
||||
|
||||
@@ -314,7 +334,7 @@ func (c *Conn) MAIL(params string) (code int, msg string) {
|
||||
if !strings.HasPrefix(strings.ToLower(params), "from:") {
|
||||
return 500, "unknown command"
|
||||
}
|
||||
if c.mode == ModeSubmission && !c.completedAuth {
|
||||
if c.mode.IsSubmission && !c.completedAuth {
|
||||
return 550, "mail to submission port must be authenticated"
|
||||
}
|
||||
|
||||
|
||||
@@ -199,6 +199,11 @@ func (s *Server) ListenAndServe() {
|
||||
}
|
||||
|
||||
func (s *Server) serve(l net.Listener, mode SocketMode) {
|
||||
// If this mode is expected to be TLS-wrapped, make it so.
|
||||
if mode.TLS {
|
||||
l = tls.NewListener(l, s.tlsConfig)
|
||||
}
|
||||
|
||||
for {
|
||||
conn, err := l.Accept()
|
||||
if err != nil {
|
||||
@@ -213,6 +218,7 @@ func (s *Server) serve(l net.Listener, mode SocketMode) {
|
||||
tc: textproto.NewConn(conn),
|
||||
mode: mode,
|
||||
tlsConfig: s.tlsConfig,
|
||||
onTLS: mode.TLS,
|
||||
userDBs: s.userDBs,
|
||||
aliasesR: s.aliasesR,
|
||||
localDomains: s.localDomains,
|
||||
|
||||
@@ -36,6 +36,7 @@ var (
|
||||
// TODO: Don't hard-code the default.
|
||||
smtpAddr = "127.0.0.1:13444"
|
||||
submissionAddr = "127.0.0.1:13999"
|
||||
submissionTLSAddr = "127.0.0.1:13777"
|
||||
|
||||
// TLS configuration to use in the clients.
|
||||
// Will contain the generated server certificate as root CA.
|
||||
@@ -46,14 +47,28 @@ var (
|
||||
// === Tests ===
|
||||
//
|
||||
|
||||
func mustDial(tb testing.TB, mode SocketMode, useTLS bool) *smtp.Client {
|
||||
func mustDial(tb testing.TB, mode SocketMode, startTLS bool) *smtp.Client {
|
||||
addr := ""
|
||||
if mode == ModeSMTP {
|
||||
switch mode {
|
||||
case ModeSMTP:
|
||||
addr = smtpAddr
|
||||
} else {
|
||||
case ModeSubmission:
|
||||
addr = submissionAddr
|
||||
case ModeSubmissionTLS:
|
||||
addr = submissionTLSAddr
|
||||
}
|
||||
c, err := smtp.Dial(addr)
|
||||
|
||||
var err error
|
||||
var conn net.Conn
|
||||
if mode.TLS {
|
||||
conn, err = tls.Dial("tcp", addr, tlsConfig)
|
||||
} else {
|
||||
conn, err = net.Dial("tcp", addr)
|
||||
}
|
||||
if err != nil {
|
||||
tb.Fatalf("(net||tls).Dial: %v", err)
|
||||
}
|
||||
c, err := smtp.NewClient(conn, "127.0.0.1")
|
||||
if err != nil {
|
||||
tb.Fatalf("smtp.Dial: %v", err)
|
||||
}
|
||||
@@ -62,7 +77,7 @@ func mustDial(tb testing.TB, mode SocketMode, useTLS bool) *smtp.Client {
|
||||
tb.Fatalf("c.Hello: %v", err)
|
||||
}
|
||||
|
||||
if useTLS {
|
||||
if startTLS {
|
||||
if ok, _ := c.Extension("STARTTLS"); !ok {
|
||||
tb.Fatalf("STARTTLS not advertised in EHLO")
|
||||
}
|
||||
@@ -153,6 +168,14 @@ func TestSubmissionWithoutAuth(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthOnTLS(t *testing.T) {
|
||||
c := mustDial(t, ModeSubmissionTLS, false)
|
||||
defer c.Close()
|
||||
|
||||
auth := smtp.PlainAuth("", "testuser@localhost", "testpasswd", "127.0.0.1")
|
||||
sendEmailWithAuth(t, c, auth)
|
||||
}
|
||||
|
||||
func TestAuthOnSMTP(t *testing.T) {
|
||||
c := mustDial(t, ModeSMTP, true)
|
||||
defer c.Close()
|
||||
@@ -285,6 +308,16 @@ func TestRepeatedStartTLS(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Test that STARTTLS fails on a TLS connection.
|
||||
func TestStartTLSOnTLS(t *testing.T) {
|
||||
c := mustDial(t, ModeSubmissionTLS, false)
|
||||
defer c.Close()
|
||||
|
||||
if err := c.StartTLS(tlsConfig); err == nil {
|
||||
t.Errorf("STARTTLS did not fail as expected")
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// === Benchmarks ===
|
||||
//
|
||||
@@ -440,6 +473,7 @@ func realMain(m *testing.M) int {
|
||||
s.AddCerts(tmpDir+"/cert.pem", tmpDir+"/key.pem")
|
||||
s.AddAddr(smtpAddr, ModeSMTP)
|
||||
s.AddAddr(submissionAddr, ModeSubmission)
|
||||
s.AddAddr(submissionTLSAddr, ModeSubmissionTLS)
|
||||
|
||||
localC := &courier.Procmail{}
|
||||
remoteC := &courier.SMTP{}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
smtp_address: ":1025"
|
||||
submission_address: ":1587"
|
||||
submission_over_tls_address: ":1465"
|
||||
monitoring_address: ":1099"
|
||||
|
||||
mail_delivery_agent_bin: "test-mda"
|
||||
|
||||
@@ -15,6 +15,10 @@ password secretpassword
|
||||
account smtpport : default
|
||||
port 1025
|
||||
|
||||
account subm_tls : default
|
||||
port 1465
|
||||
tls_starttls off
|
||||
|
||||
account baduser : default
|
||||
user unknownuser@testserver
|
||||
password secretpassword
|
||||
|
||||
@@ -31,6 +31,11 @@ if ! run_msmtp -a smtpport someone@testserver < content 2> /dev/null; then
|
||||
fail "failed auth on the SMTP port"
|
||||
fi
|
||||
|
||||
# Check deliver over the submission-over-TLS port.
|
||||
if ! run_msmtp -a subm_tls someone@testserver < content 2> /dev/null; then
|
||||
fail "failed submission over TLS"
|
||||
fi
|
||||
|
||||
if run_msmtp nobody@testserver < content 2> /dev/null; then
|
||||
fail "successfuly sent an email to a non-existent user"
|
||||
fi
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
smtp_address: ":1025"
|
||||
submission_address: ":1587"
|
||||
submission_over_tls_address: ":1465"
|
||||
monitoring_address: ":1099"
|
||||
|
||||
mail_delivery_agent_bin: "test-mda"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
smtp_address: ":1025"
|
||||
submission_address: ":1587"
|
||||
submission_over_tls_address: ":1465"
|
||||
monitoring_address: ":1099"
|
||||
|
||||
mail_delivery_agent_bin: "test-mda"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
smtp_address: ":1025"
|
||||
submission_address: ":1587"
|
||||
submission_over_tls_address: ":1465"
|
||||
monitoring_address: ":1099"
|
||||
|
||||
mail_delivery_agent_bin: "test-mda"
|
||||
|
||||
@@ -2,6 +2,7 @@ hostname: "testserver"
|
||||
|
||||
smtp_address: ":1025"
|
||||
submission_address: ":1587"
|
||||
submission_over_tls_address: ":1465"
|
||||
monitoring_address: ":1099"
|
||||
|
||||
mail_delivery_agent_bin: "test-mda"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
smtp_address: ":1025"
|
||||
submission_address: ":1587"
|
||||
submission_over_tls_address: ":1465"
|
||||
monitoring_address: ":1099"
|
||||
|
||||
mail_delivery_agent_bin: "test-mda"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
smtp_address: ":2025"
|
||||
submission_address: ":2587"
|
||||
submission_over_tls_address: ":2465"
|
||||
monitoring_address: ":2099"
|
||||
|
||||
mail_delivery_agent_bin: "test-mda"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
smtp_address: ":1025"
|
||||
submission_address: ":1587"
|
||||
submission_over_tls_address: ":1465"
|
||||
monitoring_address: ":1099"
|
||||
|
||||
mail_delivery_agent_bin: "test-mda"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
smtp_address: ":1025"
|
||||
submission_address: ":1587"
|
||||
submission_over_tls_address: ":1465"
|
||||
monitoring_address: ":1099"
|
||||
|
||||
mail_delivery_agent_bin: "test-mda"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
smtp_address: ":2025"
|
||||
submission_address: ":2587"
|
||||
submission_over_tls_address: ":2465"
|
||||
monitoring_address: ":2099"
|
||||
|
||||
mail_delivery_agent_bin: "test-mda"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
smtp_address: ":1025"
|
||||
submission_address: ":1587"
|
||||
submission_over_tls_address: ":1465"
|
||||
monitoring_address: ":1099"
|
||||
|
||||
mail_delivery_agent_bin: "test-mda"
|
||||
|
||||
Reference in New Issue
Block a user