Ver código fonte

Merge pull request #2049 from slingamn/implicittls.1

support implicit TLS for mail submission agents
tags/v2.12.0-rc1
Shivaram Lingamneni 1 ano atrás
pai
commit
3fca52ba38
Nenhuma conta vinculada ao e-mail do autor do commit
4 arquivos alterados com 40 adições e 27 exclusões
  1. 1
    0
      default.yaml
  2. 11
    5
      irc/email/email.go
  3. 27
    22
      irc/smtp/smtp.go
  4. 1
    0
      traditional.yaml

+ 1
- 0
default.yaml Ver arquivo

417
             #     port: 25
417
             #     port: 25
418
             #     username: "admin"
418
             #     username: "admin"
419
             #     password: "hunter2"
419
             #     password: "hunter2"
420
+            #     implicit-tls: false # TLS from the first byte, typically on port 465
420
             blacklist-regexes:
421
             blacklist-regexes:
421
             #    - ".*@mailinator.com"
422
             #    - ".*@mailinator.com"
422
             timeout: 60s
423
             timeout: 60s

+ 11
- 5
irc/email/email.go Ver arquivo

24
 )
24
 )
25
 
25
 
26
 type MTAConfig struct {
26
 type MTAConfig struct {
27
-	Server   string
28
-	Port     int
29
-	Username string
30
-	Password string
27
+	Server      string
28
+	Port        int
29
+	Username    string
30
+	Password    string
31
+	ImplicitTLS bool `yaml:"implicit-tls"`
31
 }
32
 }
32
 
33
 
33
 type MailtoConfig struct {
34
 type MailtoConfig struct {
132
 
133
 
133
 	var addr string
134
 	var addr string
134
 	var auth smtp.Auth
135
 	var auth smtp.Auth
136
+	var implicitTLS bool
135
 	if !config.DirectSendingEnabled() {
137
 	if !config.DirectSendingEnabled() {
136
 		addr = fmt.Sprintf("%s:%d", config.MTAReal.Server, config.MTAReal.Port)
138
 		addr = fmt.Sprintf("%s:%d", config.MTAReal.Server, config.MTAReal.Port)
137
 		if config.MTAReal.Username != "" && config.MTAReal.Password != "" {
139
 		if config.MTAReal.Username != "" && config.MTAReal.Password != "" {
138
 			auth = smtp.PlainAuth("", config.MTAReal.Username, config.MTAReal.Password, config.MTAReal.Server)
140
 			auth = smtp.PlainAuth("", config.MTAReal.Username, config.MTAReal.Password, config.MTAReal.Server)
139
 		}
141
 		}
142
+		implicitTLS = config.MTAReal.ImplicitTLS
140
 	} else {
143
 	} else {
141
 		idx := strings.IndexByte(recipient, '@')
144
 		idx := strings.IndexByte(recipient, '@')
142
 		if idx == -1 {
145
 		if idx == -1 {
149
 		addr = fmt.Sprintf("%s:smtp", mx)
152
 		addr = fmt.Sprintf("%s:smtp", mx)
150
 	}
153
 	}
151
 
154
 
152
-	return smtp.SendMail(addr, auth, config.HeloDomain, config.Sender, []string{recipient}, msg, config.RequireTLS, config.Timeout)
155
+	return smtp.SendMail(
156
+		addr, auth, config.HeloDomain, config.Sender, []string{recipient}, msg,
157
+		config.RequireTLS, implicitTLS, config.Timeout,
158
+	)
153
 }
159
 }

+ 27
- 22
irc/smtp/smtp.go Ver arquivo

55
 
55
 
56
 // Dial returns a new Client connected to an SMTP server at addr.
56
 // Dial returns a new Client connected to an SMTP server at addr.
57
 // The addr must include a port, as in "mail.example.com:smtp".
57
 // The addr must include a port, as in "mail.example.com:smtp".
58
-func Dial(addr string, timeout time.Duration) (*Client, error) {
58
+func Dial(addr string, timeout time.Duration, implicitTLS bool) (*Client, error) {
59
 	var conn net.Conn
59
 	var conn net.Conn
60
 	var err error
60
 	var err error
61
+	dialer := net.Dialer{
62
+		Timeout: timeout,
63
+	}
61
 	start := time.Now()
64
 	start := time.Now()
62
-	if timeout == 0 {
63
-		conn, err = net.Dial("tcp", addr)
65
+	if !implicitTLS {
66
+		conn, err = dialer.Dial("tcp", addr)
64
 	} else {
67
 	} else {
65
-		conn, err = net.DialTimeout("tcp", addr, timeout)
68
+		conn, err = tls.DialWithDialer(&dialer, "tcp", addr, nil)
66
 	}
69
 	}
67
 	if err != nil {
70
 	if err != nil {
68
 		return nil, err
71
 		return nil, err
338
 // functionality. Higher-level packages exist outside of the standard
341
 // functionality. Higher-level packages exist outside of the standard
339
 // library.
342
 // library.
340
 // XXX: modified in Ergo to add `requireTLS`, `heloDomain`, and `timeout` arguments
343
 // XXX: modified in Ergo to add `requireTLS`, `heloDomain`, and `timeout` arguments
341
-func SendMail(addr string, a Auth, heloDomain string, from string, to []string, msg []byte, requireTLS bool, timeout time.Duration) error {
344
+func SendMail(addr string, a Auth, heloDomain string, from string, to []string, msg []byte, requireTLS, implicitTLS bool, timeout time.Duration) error {
342
 	if err := validateLine(from); err != nil {
345
 	if err := validateLine(from); err != nil {
343
 		return err
346
 		return err
344
 	}
347
 	}
347
 			return err
350
 			return err
348
 		}
351
 		}
349
 	}
352
 	}
350
-	c, err := Dial(addr, timeout)
353
+	c, err := Dial(addr, timeout, implicitTLS)
351
 	if err != nil {
354
 	if err != nil {
352
 		return err
355
 		return err
353
 	}
356
 	}
355
 	if err = c.Hello(heloDomain); err != nil {
358
 	if err = c.Hello(heloDomain); err != nil {
356
 		return err
359
 		return err
357
 	}
360
 	}
358
-	if ok, _ := c.Extension("STARTTLS"); ok {
359
-		var config *tls.Config
360
-		if requireTLS {
361
-			config = &tls.Config{ServerName: c.serverName}
362
-		} else {
363
-			// if TLS isn't a hard requirement, don't verify the certificate either,
364
-			// since a MITM attacker could just remove the STARTTLS advertisement
365
-			config = &tls.Config{InsecureSkipVerify: true}
366
-		}
367
-		if testHookStartTLS != nil {
368
-			testHookStartTLS(config)
369
-		}
370
-		if err = c.StartTLS(config); err != nil {
371
-			return err
361
+	if !implicitTLS {
362
+		if ok, _ := c.Extension("STARTTLS"); ok {
363
+			var config *tls.Config
364
+			if requireTLS {
365
+				config = &tls.Config{ServerName: c.serverName}
366
+			} else {
367
+				// if TLS isn't a hard requirement, don't verify the certificate either,
368
+				// since a MITM attacker could just remove the STARTTLS advertisement
369
+				config = &tls.Config{InsecureSkipVerify: true}
370
+			}
371
+			if testHookStartTLS != nil {
372
+				testHookStartTLS(config)
373
+			}
374
+			if err = c.StartTLS(config); err != nil {
375
+				return err
376
+			}
377
+		} else if requireTLS {
378
+			return errors.New("TLS required, but not negotiated")
372
 		}
379
 		}
373
-	} else if requireTLS {
374
-		return errors.New("TLS required, but not negotiated")
375
 	}
380
 	}
376
 	if a != nil && c.ext != nil {
381
 	if a != nil && c.ext != nil {
377
 		if _, ok := c.ext["AUTH"]; !ok {
382
 		if _, ok := c.ext["AUTH"]; !ok {

+ 1
- 0
traditional.yaml Ver arquivo

390
             #     port: 25
390
             #     port: 25
391
             #     username: "admin"
391
             #     username: "admin"
392
             #     password: "hunter2"
392
             #     password: "hunter2"
393
+            #     implicit-tls: false # TLS from the first byte, typically on port 465
393
             blacklist-regexes:
394
             blacklist-regexes:
394
             #    - ".*@mailinator.com"
395
             #    - ".*@mailinator.com"
395
             timeout: 60s
396
             timeout: 60s

Carregando…
Cancelar
Salvar