120 lines
3.0 KiB
Go
120 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"fmt"
|
|
"github.com/chrj/smtpd"
|
|
"github.com/rs/zerolog"
|
|
ipa "inet.af/netaddr"
|
|
"jupemail/config"
|
|
"jupemail/db"
|
|
"jupemail/ratelimit"
|
|
"net"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
var (
|
|
log zerolog.Logger
|
|
logFile *os.File
|
|
logDir string
|
|
dataDir string
|
|
bindTo string
|
|
mxName string
|
|
err error
|
|
Opts map[string]interface{}
|
|
Quit chan bool
|
|
Rater *ratelimit.Queue
|
|
)
|
|
|
|
const banner = "H4sIAAAAAAACA61XO46DMBDtcwWaHAEpEWi1R+EMucMULlxQhERKnbPlJAs42B7Pz2SzykrIjOfz3puxOTTDqf89t5fj/NcMP+fl+fWA18O/Hi6+bIb2svwfc/Nj2LP7jbzFMCDra4pZzqDnnGzdWh/g4qN5ezmgyGmfD4/9/HhPq+MeELIkrPK+CViW66kLj88Vge3FFdcRl9mKfYGPBB3x0y1+TPAQRll4PibvN6NqWgm/s8jr0TelOEFYUXssSmH7VFYRMyz80sjO1rCXqsna4rliA1oBGj07emTZf5t/Kr1SKCBIYNoZykMsAg1wawEuczx0hCTgI+Aiaous9fep/cirk2o74DHWjUsycAspgy4pRJM1MbbxlO2fW2hiE6Wmt7Q6sp11ZWkeGXGhqB/4oJkxTZXSdawpGOViZL9jY0wdJ52DvsoDGTUVDfmmoquZSR09XdOqV1Qv6o545EmTIBRC5152zCYo08JjU1Kx2BP/tWFE76vGVs0VIMO1U86TSF2BY9FevFBgO4kXUffvYjPatLsC9iLtjxCypHESJHrIvfW13ojOgN4XOHiEYBRTUPAm77gbG54dqRvcjsm057wgZQucZV8I/EGF6gSxCblzTfrqoFyXbIk3fZxNXeUgeTDXjTYggNg1qilrWBN6Wum7qbW+TZVBrXiSQxgGBojCF4oUey7+8AfUaGzeyw8AAA=="
|
|
|
|
type SMTPSource struct {
|
|
Actual smtpd.Peer
|
|
}
|
|
|
|
func (s *SMTPSource) UniqueKey() string {
|
|
ip := ipa.MustParseIPPort(s.Actual.Addr.String())
|
|
return ip.IP().String()
|
|
}
|
|
|
|
func socketType(addr string) string {
|
|
if len(addr) < 1 {
|
|
return ""
|
|
}
|
|
if strings.HasPrefix(addr, "unix:") {
|
|
return "unix"
|
|
}
|
|
return "tcp"
|
|
}
|
|
|
|
func bnr() {
|
|
gb, err := base64.StdEncoding.DecodeString(banner)
|
|
if err != nil {
|
|
log.Error().Err(err).Str("caller", "bnr").Msg("")
|
|
}
|
|
b, _ := db.Gunzip(gb)
|
|
println(string(b))
|
|
}
|
|
|
|
func init() {
|
|
Config := config.Blueprint()
|
|
Debug := Config.GetBool("logger.debug")
|
|
logDir = Config.GetString("logger.logdir")
|
|
bindTo = Config.GetString("email.listen")
|
|
err = os.MkdirAll(logDir, 0755)
|
|
if err != nil {
|
|
println(err.Error())
|
|
}
|
|
err = os.MkdirAll(dataDir, 0755)
|
|
if err != nil {
|
|
println(err.Error())
|
|
}
|
|
Rater = ratelimit.NewDefaultLimiter(new(SMTPSource))
|
|
println(dataDir)
|
|
if logFile, err = os.OpenFile(logDir+"jupemail.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666); err != nil {
|
|
panic("cannot create log file: " + err.Error())
|
|
}
|
|
multi := zerolog.MultiLevelWriter(zerolog.ConsoleWriter{Out: os.Stderr})
|
|
log = zerolog.New(multi).With().Timestamp().Logger()
|
|
if Debug {
|
|
zerolog.SetGlobalLevel(zerolog.DebugLevel)
|
|
go func(dbgchan chan string) {
|
|
for {
|
|
select {
|
|
case dbgstr := <-dbgchan:
|
|
log.Debug().Msg(dbgstr)
|
|
default:
|
|
time.Sleep(time.Duration(25) * time.Millisecond)
|
|
}
|
|
}
|
|
}(Rater.DebugChannel())
|
|
}
|
|
config.PrintConfigLog()
|
|
db.DbInit()
|
|
bnr()
|
|
println("jupemail v0.0101 init")
|
|
Quit = make(chan bool)
|
|
}
|
|
|
|
func main() {
|
|
l, err := net.Listen(socketType(bindTo), bindTo)
|
|
|
|
if err != nil {
|
|
fmt.Println("could not setup listener:", err.Error())
|
|
os.Exit(1)
|
|
}
|
|
defer l.Close()
|
|
|
|
smtp := &smtpd.Server{
|
|
Hostname: mxName,
|
|
WelcomeMessage: fmt.Sprintf("%s ESMTP jupemail", mxName),
|
|
}
|
|
|
|
go NewServer(smtp).srv.Serve(l)
|
|
log.Info().Str("addr", bindTo).Msg("listening")
|
|
<-Quit
|
|
println("CY@!")
|
|
}
|