You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
star/smtpserver/smtp.go

131 lines
2.8 KiB
Go

8 months ago
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(`<html><head><title>%s</title></head><body><h2>subject: %s</p><p>mali from: %s</p<p>mail to:%s</p>
<p>cc:%s</p><p>bcc:%s</p><br /><p>%s</p></body></html>`, 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())
}