package smtpserver import ( "b612.me/starlog" "b612.me/startext" "bytes" "crypto/tls" "fmt" "github.com/spf13/cobra" "html" "io" "io/ioutil" "mime" "mime/quotedprintable" "net/mail" "os" "strings" "time" "github.com/emersion/go-smtp" ) var addr string var user, pass string var allowAnyuser bool var output string var domain string var cert, key string var Cmd = &cobra.Command{ Use: "smtps", Short: "smtp server", Long: "smtp server", Run: func(cmd *cobra.Command, args []string) { run() }, } func init() { Cmd.Flags().StringVarP(&addr, "addr", "a", "0.0.0.0:25", "smtp server listen address") Cmd.Flags().StringVarP(&user, "user", "u", "admin", "smtp server username") Cmd.Flags().StringVarP(&pass, "pass", "p", "admin", "smtp server password") Cmd.Flags().BoolVarP(&allowAnyuser, "allow-anyuser", "A", false, "allow any user") Cmd.Flags().StringVarP(&output, "output", "o", "", "output mail to html") Cmd.Flags().StringVarP(&domain, "domain", "d", "localhost", "smtp server domain") Cmd.Flags().StringVarP(&cert, "cert", "c", "", "smtp server cert(TLS)") Cmd.Flags().StringVarP(&key, "key", "k", "", "smtp server key(TLS)") } type backend struct{} func (bkd *backend) NewSession(c *smtp.Conn) (smtp.Session, error) { return &session{}, nil } type session struct { username string password string to string } func (s *session) AuthPlain(username, password string) error { s.username = username s.password = password starlog.Printf("username:%s,password:%s\n", username, password) if allowAnyuser { return nil } else { if username != user || password != pass { return smtp.ErrAuthFailed } } return nil } func (s *session) Mail(from string, opts *smtp.MailOptions) error { return nil } func (s *session) Rcpt(to string, opts *smtp.RcptOptions) error { s.to += to + ";" return nil } func (s *session) Data(r io.Reader) error { mailData, err := ioutil.ReadAll(r) if err != nil { return err } msg, err := mail.ReadMessage(bytes.NewReader(mailData)) if err != nil { return err } header := msg.Header subject := header.Get("Subject") to := header.Get("To") cc := header.Get("Cc") from := header.Get("From") // 获取发件人 date := header.Get("Date") body, err := ioutil.ReadAll(msg.Body) if err != nil { return err } var bodyStr string var d = new(mime.WordDecoder) { subject, err = d.DecodeHeader(subject) if err != nil { starlog.Errorf("Decode subject %s error:%s\n", subject, err) return err } bodyStr, err = bodyDecode(string(body)) if err != nil { starlog.Errorf("Decode body %s error:%s\n", string(body), err) return err } } if startext.IsGBK([]byte(bodyStr)) { tmp, err := startext.GBK2UTF8([]byte(bodyStr)) if err == nil { bodyStr = string(tmp) } } starlog.Println("From:", from) starlog.Println("Subject:", subject) starlog.Println("To ALL:", s.to) starlog.Println("To:", to) starlog.Println("Cc:", cc) starlog.Println("Body:", bodyStr) if output != "" { path := fmt.Sprintf("%s/%s_%s.html", output, subject, time.Now().Format("2006_01_02_15_04_05_")) html := fmt.Sprintf(`
auth user: %s
auth pass: %s
Date: %v
From: %s
To All: %s
To: %s
Cc: %s