Blame


1 925168e0 2022-04-14 o package mailmux
2 925168e0 2022-04-14 o
3 925168e0 2022-04-14 o import (
4 925168e0 2022-04-14 o "errors"
5 925168e0 2022-04-14 o "fmt"
6 71bdede3 2022-04-21 o "io"
7 71bdede3 2022-04-21 o "net"
8 71bdede3 2022-04-21 o "os"
9 925168e0 2022-04-14 o )
10 925168e0 2022-04-14 o
11 925168e0 2022-04-14 o type Server struct {
12 71bdede3 2022-04-21 o ln net.Listener
13 71bdede3 2022-04-21 o Aliases AliasStore
14 71bdede3 2022-04-21 o Users UserStore
15 925168e0 2022-04-14 o }
16 925168e0 2022-04-14 o
17 71bdede3 2022-04-21 o func (srv *Server) ListenAndServe() error {
18 71bdede3 2022-04-21 o if srv.ln == nil {
19 71bdede3 2022-04-21 o return errors.New("nil listener")
20 925168e0 2022-04-14 o }
21 71bdede3 2022-04-21 o return srv.Serve(srv.ln)
22 925168e0 2022-04-14 o }
23 925168e0 2022-04-14 o
24 71bdede3 2022-04-21 o func (srv *Server) Serve(ln net.Listener) error {
25 71bdede3 2022-04-21 o if ln == nil {
26 71bdede3 2022-04-21 o return errors.New("nil listener")
27 925168e0 2022-04-14 o }
28 71bdede3 2022-04-21 o for {
29 71bdede3 2022-04-21 o conn, err := ln.Accept()
30 71bdede3 2022-04-21 o if err != nil {
31 71bdede3 2022-04-21 o return err
32 71bdede3 2022-04-21 o }
33 71bdede3 2022-04-21 o go func() {
34 71bdede3 2022-04-21 o if err := srv.handleConn(conn); err != nil {
35 71bdede3 2022-04-21 o fmt.Fprintln(os.Stderr, err)
36 71bdede3 2022-04-21 o }
37 71bdede3 2022-04-21 o conn.Close()
38 71bdede3 2022-04-21 o }()
39 925168e0 2022-04-14 o }
40 71bdede3 2022-04-21 o return errors.New("unreachable?")
41 925168e0 2022-04-14 o }
42 925168e0 2022-04-14 o
43 71bdede3 2022-04-21 o func (srv *Server) handleConn(conn net.Conn) error {
44 71bdede3 2022-04-21 o tmsg, err := ParseMcall(conn)
45 925168e0 2022-04-14 o if err != nil {
46 71bdede3 2022-04-21 o err = fmt.Errorf("parse mcall: %w", err)
47 71bdede3 2022-04-21 o rerror(conn, err.Error())
48 71bdede3 2022-04-21 o return err
49 925168e0 2022-04-14 o }
50 71bdede3 2022-04-21 o if tmsg.Type != Tauth {
51 71bdede3 2022-04-21 o rerror(conn, "unauthorised")
52 71bdede3 2022-04-21 o return nil
53 925168e0 2022-04-14 o }
54 71bdede3 2022-04-21 o if err := srv.Users.Authenticate(tmsg.Username, Password(tmsg.Password)); err != nil {
55 71bdede3 2022-04-21 o rerror(conn, "authentication failed")
56 71bdede3 2022-04-21 o return err
57 71bdede3 2022-04-21 o }
58 71bdede3 2022-04-21 o rmsg := &Mcall{Type: Rauth, Username: tmsg.Username}
59 71bdede3 2022-04-21 o writeMcall(conn, rmsg)
60 925168e0 2022-04-14 o
61 71bdede3 2022-04-21 o user := tmsg.Username
62 71bdede3 2022-04-21 o for {
63 71bdede3 2022-04-21 o tmsg, err := ParseMcall(conn)
64 71bdede3 2022-04-21 o if errors.Is(err, io.EOF) {
65 71bdede3 2022-04-21 o return nil
66 71bdede3 2022-04-21 o } else if err != nil {
67 71bdede3 2022-04-21 o rerror(conn, err.Error())
68 71bdede3 2022-04-21 o continue
69 71bdede3 2022-04-21 o }
70 71bdede3 2022-04-21 o rmsg := &Mcall{}
71 71bdede3 2022-04-21 o switch tmsg.Type {
72 71bdede3 2022-04-21 o case Tauth:
73 71bdede3 2022-04-21 o rmsg = &Mcall{Type: Rerror, Error: "already authenticated"}
74 71bdede3 2022-04-21 o case Tlist:
75 71bdede3 2022-04-21 o rmsg = srv.listAliases(user)
76 71bdede3 2022-04-21 o case Tcreate:
77 71bdede3 2022-04-21 o rmsg = srv.createAlias(user)
78 71bdede3 2022-04-21 o default:
79 71bdede3 2022-04-21 o rmsg = &Mcall{Type: Rerror, Error: "this tmessage not implemented yet"}
80 71bdede3 2022-04-21 o }
81 71bdede3 2022-04-21 o writeMcall(conn, rmsg)
82 925168e0 2022-04-14 o }
83 925168e0 2022-04-14 o }
84 925168e0 2022-04-14 o
85 71bdede3 2022-04-21 o func (srv *Server) createAlias(username string) *Mcall {
86 71bdede3 2022-04-21 o alias, err := srv.Aliases.Create(username)
87 925168e0 2022-04-14 o if err != nil {
88 925168e0 2022-04-14 o return &Mcall{Type: Rerror, Error: err.Error()}
89 925168e0 2022-04-14 o }
90 71bdede3 2022-04-21 o return &Mcall{Type: Rcreate, Aliases: []Alias{alias}}
91 925168e0 2022-04-14 o }
92 925168e0 2022-04-14 o
93 71bdede3 2022-04-21 o func (srv *Server) listAliases(username string) *Mcall {
94 71bdede3 2022-04-21 o a, err := srv.Aliases.Aliases(username)
95 925168e0 2022-04-14 o if err != nil {
96 71bdede3 2022-04-21 o return &Mcall{Type: Rerror, Error: fmt.Sprintf("aliases for %s: %v", username, err)}
97 925168e0 2022-04-14 o }
98 71bdede3 2022-04-21 o return &Mcall{Type: Rlist, Aliases: a}
99 925168e0 2022-04-14 o }