package smtpserver import ( "b612.me/starlog" "bytes" "flag" "fmt" "github.com/spf13/cobra" "io" "io/ioutil" "net/mail" "os" "github.com/emersion/go-smtp" ) var addr string var user, pass string var allowAnyuser bool var output string var domain string var Cmd = &cobra.Command{ Use: "smtp", 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") } 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") cc := header.Get("Cc") bcc := header.Get("Bcc") from := header.Get("From") // 获取发件人 starlog.Println("From:", from) starlog.Println("Subject:", subject) starlog.Println("Cc:", cc) starlog.Println("Bcc:", bcc) // Read the body body, err := ioutil.ReadAll(msg.Body) if err != nil { return err } starlog.Println("Body:", string(body)) if output != "" { path := output + "/" + subject + ".html" html := fmt.Sprintf(`
mali from: %s
mail to:%scc:%s
bcc:%s
%s
`, subject, subject, from, s.to, cc, bcc, string(body)) os.WriteFile(path, []byte(html), 0644) } return nil } func (s *session) Reset() {} func (s *session) Logout() error { return nil } func run() { flag.Parse() s := smtp.NewServer(&backend{}) s.Addr = addr s.Domain = domain s.AllowInsecureAuth = true s.Debug = os.Stdout starlog.Infoln("Starting SMTP server at", addr) starlog.Errorln(s.ListenAndServe()) }