From b27e7a73337659aca8ed1aadd4b907048b1f598c Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Mon, 13 Jan 2025 16:33:50 +0800 Subject: Listen to IMAP --- config.go | 4 ++++ go.mod | 2 ++ go.sum | 4 ++++ maild.scfg | 5 +++++ main.go | 1 + serve_imap.go | 40 ++++++++++++++++++++++++++++++++++++++++ serve_mx.go | 9 +++++++-- 7 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 serve_imap.go diff --git a/config.go b/config.go index e7d6aa4..92bec3e 100644 --- a/config.go +++ b/config.go @@ -25,6 +25,10 @@ var config struct { Net string `scfg:"net"` Addr string `scfg:"addr"` } `scfg:"mx"` + IMAP struct { + Net string `scfg:"net"` + Addr string `scfg:"addr"` + } `scfg:"imap"` _tls_config *tls.Config } var ( diff --git a/go.mod b/go.mod index 2ff8d98..de766ee 100644 --- a/go.mod +++ b/go.mod @@ -3,11 +3,13 @@ module go.lindenii.runxiyu.org/maild go 1.23.4 require ( + github.com/emersion/go-imap/v2 v2.0.0-beta.4 github.com/jackc/pgx/v5 v5.7.2 go.lindenii.runxiyu.org/lindenii-common v0.0.0-20250113062520-2daa71bfa256 ) require ( + github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect diff --git a/go.sum b/go.sum index 2be52d7..d9cbdd6 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,10 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emersion/go-imap/v2 v2.0.0-beta.4 h1:BS7+kUVhe/jfuFWgn8li0AbCKBIDoNvqJWsRJppltcc= +github.com/emersion/go-imap/v2 v2.0.0-beta.4/go.mod h1:BZTFHsS1hmgBkFlHqbxGLXk2hnRqTItUgwjSSCsYNAk= +github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43 h1:hH4PQfOndHDlpzYfLAAfl63E8Le6F2+EL/cdhlkyRJY= +github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= diff --git a/maild.scfg b/maild.scfg index c26f388..efc99ca 100644 --- a/maild.scfg +++ b/maild.scfg @@ -14,3 +14,8 @@ mx { net tcp addr :1025 } + +imap { + net tcp + addr :1993 +} diff --git a/main.go b/main.go index 51540f9..d4b3696 100644 --- a/main.go +++ b/main.go @@ -17,6 +17,7 @@ func main() { clog.Fatal(1, "Error while loading configuration file: "+err.Error()) } + go serve_imap() go serve_mx() deadlock := make(chan struct{}) diff --git a/serve_imap.go b/serve_imap.go new file mode 100644 index 0000000..f1d195d --- /dev/null +++ b/serve_imap.go @@ -0,0 +1,40 @@ +package main + +import ( + "crypto/tls" + + "github.com/emersion/go-imap/v2" + "github.com/emersion/go-imap/v2/imapserver" + "go.lindenii.runxiyu.org/lindenii-common/clog" +) + +func serve_imap() { + var tls_config *tls.Config + var imap_net, imap_addr string + config_consistent_run(func() { + tls_config = config._tls_config + imap_net = config.IMAP.Net + imap_addr = config.IMAP.Addr + }) + listener, err := tls.Listen(imap_net, imap_addr, tls_config) + if err != nil { + clog.Fatal(1, "IMAP: Cannot listen TLS: "+err.Error()) + } + clog.Info("IMAP: Listening via " + imap_net + " on " + imap_addr) + + + server := imapserver.New(&imapserver.Options{ + NewSession: func(conn *imapserver.Conn) (imapserver.Session, *imapserver.GreetingData, error) { + return nil, nil, nil + }, + Caps: imap.CapSet{ + imap.CapIMAP4rev1: {}, + imap.CapIMAP4rev2: {}, + }, + DebugWriter: nil, // TODO + }) + err = server.Serve(listener) + if err != nil { + clog.Fatal(1, "IMAP: Failed serving: "+err.Error()) + } +} diff --git a/serve_mx.go b/serve_mx.go index f3c1527..32710be 100644 --- a/serve_mx.go +++ b/serve_mx.go @@ -232,12 +232,17 @@ func handle_mx_recv_conn(ctx context.Context, net_conn net.Conn) error { } func serve_mx() { - listener, err := net.Listen(config.MX.Net, config.MX.Addr) + var mx_net, mx_addr string + config_consistent_run(func(){ + mx_net = config.MX.Net + mx_addr = config.MX.Addr + }) + listener, err := net.Listen(mx_net, mx_addr) if err != nil { clog.Fatal(1, "MX: Cannot listen: "+err.Error()) } defer listener.Close() - clog.Info("MX: Listening via " + config.MX.Net + " on " + config.MX.Addr) + clog.Info("MX: Listening via " + mx_net + " on " + mx_addr) for { conn, err := listener.Accept() -- cgit v1.2.3