backend.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package guerrilla
  2. import (
  3. "bufio"
  4. "errors"
  5. "io"
  6. "net"
  7. )
  8. // Backend accepts the relieved messages, and store/deliver/process them
  9. type Backend interface {
  10. Initialize(BackendConfig) error
  11. Process(client *Client, user, host string) string
  12. }
  13. const CommandMaxLength = 1024
  14. // TODO: cleanup
  15. type Client struct {
  16. State int
  17. Helo string
  18. MailFrom string
  19. RcptTo string
  20. Response string
  21. Address string
  22. Data string
  23. Subject string
  24. Hash string
  25. Time int64
  26. TLS bool
  27. Conn net.Conn
  28. Bufin *SMTPBufferedReader
  29. Bufout *bufio.Writer
  30. KillTime int64
  31. Errors int
  32. ClientID int64
  33. SavedNotify chan int
  34. }
  35. var InputLimitExceeded = errors.New("Line too long") // 500 Line too long.
  36. // we need to adjust the limit, so we embed io.LimitedReader
  37. type adjustableLimitedReader struct {
  38. R *io.LimitedReader
  39. }
  40. // bolt this on so we can adjust the limit
  41. func (alr *adjustableLimitedReader) setLimit(n int64) {
  42. alr.R.N = n
  43. }
  44. // this just delegates to the underlying reader in order to satisfy the Reader interface
  45. // Since the vanilla limited reader returns io.EOF when the limit is reached, we need a more specific
  46. // error so that we can distinguish when a limit is reached
  47. func (alr *adjustableLimitedReader) Read(p []byte) (n int, err error) {
  48. n, err = alr.R.Read(p)
  49. if err == io.EOF && alr.R.N <= 0 {
  50. // return our custom error since std lib returns EOF
  51. err = InputLimitExceeded
  52. }
  53. return
  54. }
  55. // allocate a new adjustableLimitedReader
  56. func newAdjustableLimitedReader(r io.Reader, n int64) *adjustableLimitedReader {
  57. lr := &io.LimitedReader{R: r, N: n}
  58. return &adjustableLimitedReader{lr}
  59. }
  60. // This is a bufio.Reader what will use our adjustable limit reader
  61. // We 'extend' buffio to have the limited reader feature
  62. type SMTPBufferedReader struct {
  63. *bufio.Reader
  64. alr *adjustableLimitedReader
  65. }
  66. // delegate to the adjustable limited reader
  67. func (sbr *SMTPBufferedReader) SetLimit(n int64) {
  68. sbr.alr.setLimit(n)
  69. }
  70. // allocate a new smtpBufferedReader
  71. func NewSMTPBufferedReader(rd io.Reader) *SMTPBufferedReader {
  72. alr := newAdjustableLimitedReader(rd, CommandMaxLength)
  73. s := &SMTPBufferedReader{bufio.NewReader(alr), alr}
  74. return s
  75. }