Exemplo n.º 1
0
func makeMailHandler(mandrillAPI *gochimp.MandrillAPI, sendLimiter *rerate.Limiter, spamLimiter *rerate.Limiter) func(smtpd.Peer, smtpd.Envelope) error {
	return func(peer smtpd.Peer, env smtpd.Envelope) error {
		// Validate data before sending them
		if _, err := mail.ReadMessage(bytes.NewReader(env.Data)); err != nil {
			return err
		}

		response, err := mandrillAPI.MessageSendRaw(string(env.Data), env.Recipients, gochimp.Recipient{Email: env.Sender}, false)
		if err != nil {
			log.WithFields(log.Fields{
				"peer":  peer,
				"error": err,
			}).Info("Error sending message")
			return smtpd.Error{Code: 451, Message: "Error with Remote API"}
		}
		if response[0].Status == "rejected" && response[0].RejectedReason == "spam" {
			log.WithFields(log.Fields{
				"peer":           peer,
				"RejectedReason": response[0].RejectedReason,
			}).Info("Message filtered as SPAM")

			if err := spamLimiter.Inc(peer.HeloName); err != nil {
				log.WithFields(log.Fields{
					"heloName": peer.HeloName,
					"error":    err,
				}).Warn("Can't increment send")
			}
			return smtpd.Error{Code: 451, Message: "Spam filtered, increment rate limit"}
		}

		return nil
	}
}
Exemplo n.º 2
0
func makeHeloChecker(sendLimiter *rerate.Limiter, spamLimiter *rerate.Limiter) func(smtpd.Peer, string) error {
	return func(peer smtpd.Peer, heloName string) error {
		if err := sendLimiter.Inc(heloName); err != nil {
			log.WithFields(log.Fields{
				"heloName": heloName,
				"error":    err,
			}).Warn("Can't increment send")
		}

		if exc, _ := sendLimiter.Exceeded(heloName); exc {
			log.WithFields(log.Fields{
				"rateLimit": "send",
				"peer":      peer,
			}).Warn("rateLimit exceeded")
			return smtpd.Error{Code: 451, Message: "Rate Limit exceeded"}
		}
		if exc, _ := spamLimiter.Exceeded(heloName); exc {
			log.WithFields(log.Fields{
				"rateLimit": "spam",
				"peer":      peer,
			}).Warn("rateLimit exceeded")
			return smtpd.Error{Code: 451, Message: "Rate Limit exceeded"}
		}
		return nil
	}
}