remotes.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. package main
  2. import (
  3. "fmt"
  4. "net/smtp"
  5. "net/url"
  6. )
  7. type Remote struct {
  8. SkipVerify bool
  9. Auth smtp.Auth
  10. Scheme string
  11. Hostname string
  12. Port string
  13. Addr string
  14. Sender string
  15. }
  16. // ParseRemote creates a remote from a given url in the following format:
  17. //
  18. // smtp://[user[:password]@][netloc][:port][/remote_sender][?param1=value1&...]
  19. // smtps://[user[:password]@][netloc][:port][/remote_sender][?param1=value1&...]
  20. // starttls://[user[:password]@][netloc][:port][/remote_sender][?param1=value1&...]
  21. //
  22. // Supported Params:
  23. // - skipVerify: can be "true" or empty to prevent ssl verification of remote server's certificate.
  24. // - auth: can be "login" to trigger "LOGIN" auth instead of "PLAIN" auth
  25. func ParseRemote(remoteURL string) (*Remote, error) {
  26. u, err := url.Parse(remoteURL)
  27. if err != nil {
  28. return nil, err
  29. }
  30. if u.Scheme != "smtp" && u.Scheme != "smtps" && u.Scheme != "starttls" {
  31. return nil, fmt.Errorf("'%s' is not a supported relay scheme", u.Scheme)
  32. }
  33. hostname, port := u.Hostname(), u.Port()
  34. if port == "" {
  35. switch u.Scheme {
  36. case "smtp":
  37. port = "25"
  38. case "smtps":
  39. port = "465"
  40. case "starttls":
  41. port = "587"
  42. }
  43. }
  44. q := u.Query()
  45. r := &Remote{
  46. Scheme: u.Scheme,
  47. Hostname: hostname,
  48. Port: port,
  49. Addr: fmt.Sprintf("%s:%s", hostname, port),
  50. }
  51. if u.User != nil {
  52. pass, _ := u.User.Password()
  53. user := u.User.Username()
  54. if hasAuth, authVal := q.Has("auth"), q.Get("auth"); hasAuth {
  55. if authVal != "login" {
  56. return nil, fmt.Errorf("Auth must be login or not present, received '%s'", authVal)
  57. }
  58. r.Auth = LoginAuth(user, pass)
  59. } else {
  60. r.Auth = smtp.PlainAuth("", user, pass, u.Hostname())
  61. }
  62. }
  63. if hasVal, skipVerify := q.Has("skipVerify"), q.Get("skipVerify"); hasVal && skipVerify != "false" {
  64. r.SkipVerify = true
  65. }
  66. if u.Path != "" {
  67. r.Sender = u.Path[1:]
  68. }
  69. return r, nil
  70. }