From 42c5f39700c6ba95a6b924be807e8cddd69c3bdd Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Mon, 13 Jan 2025 12:02:49 +0800 Subject: Add PostgreSQL mail store support --- mx_recv.go | 49 ++++++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 25 deletions(-) (limited to 'mx_recv.go') diff --git a/mx_recv.go b/mx_recv.go index f79ff6e..221d8eb 100644 --- a/mx_recv.go +++ b/mx_recv.go @@ -3,7 +3,9 @@ package main import ( "bufio" "bytes" + "context" "crypto/tls" + "errors" "net" "slices" "strings" @@ -32,7 +34,7 @@ type mx_recv_session struct { current_mail_from string current_rcpt_to []string server_state server_state_t - // ctx context.Context + ctx context.Context } func (session *mx_recv_session) handle() error { @@ -128,14 +130,20 @@ func (session *mx_recv_session) handle() error { _ = session.buf_conn.Flush() break } - recipient, _, _ := mailkit.Strip_angle_brackets(param[len("TO:"):]) - ok := true // XXX: Check routing table - if !ok { - _, _ = session.buf_conn.WriteString("550 5.1.1 <" + recipient + ">: Recipient address rejected: User unknown in local recipient table\r\n") + recipient_address, _, _ := mailkit.Strip_angle_brackets(param[len("TO:"):]) + var count int + err := session.db.QueryRow(session.ctx, "SELECT COUNT (*) FROM addresses WHERE address = $1", recipient_address).Scan(&count) + if err != nil { + _, _ = session.buf_conn.WriteString("451 Internal error: " + err.Error() + "\r\n") _ = session.buf_conn.Flush() - break switch_cmd + break } - session.current_rcpt_to = append(session.current_rcpt_to, recipient) + if count == 0 { + _, _ = session.buf_conn.WriteString("550 5.1.1 Recipient address rejected: Local recipients not found: " + recipient_address + "\r\n") + _ = session.buf_conn.Flush() + break + } + session.current_rcpt_to = append(session.current_rcpt_to, recipient_address) session.server_state = server_state_rcpt _, _ = session.buf_conn.WriteString("250 2.1.5 Ok\r\n") _ = session.buf_conn.Flush() @@ -176,24 +184,14 @@ func (session *mx_recv_session) handle() error { if err != nil { return err } - { - inboxes_to_deliver_to := make(map[string]struct{}) - for _, recipient := range session.current_rcpt_to { - inbox, ok := "/tmp", true // XXX: Check routing table - if !ok { - _, _ = session.buf_conn.WriteString("550 5.1.1 <" + recipient + ">: Recipient address rejected: User unknown in local recipient table\r\n") - break switch_cmd - } - inboxes_to_deliver_to[inbox] = struct{}{} - } - for inbox := range inboxes_to_deliver_to { - err = deliver_to_local_directory(session.current_mail_from, session.current_rcpt_to, current_data, inbox) - } - } - if err == nil { - _, _ = session.buf_conn.WriteString("250 2.0.0 Ok: Accepted\r\n") - } else { + err = deliver_local(session.ctx, session.db, session.current_mail_from, session.current_rcpt_to, current_data, session.current_rcpt_to) + var err_local_recipients_not_found *err_local_recipients_not_found_t + if errors.As(err, &err_local_recipients_not_found) { + _, _ = session.buf_conn.WriteString("550 5.1.1 Recipient address rejected: " + err_local_recipients_not_found.Error() + "\r\n") + } else if err != nil { _, _ = session.buf_conn.WriteString("500 2.0.0 Error: " + err.Error() + "\r\n") + } else { + _, _ = session.buf_conn.WriteString("250 2.0.0 Ok: Accepted\r\n") } _ = session.buf_conn.Flush() session.server_state = server_state_helo @@ -217,9 +215,10 @@ func (session *mx_recv_session) handle() error { } } -func handle_mx_recv_conn(net_conn net.Conn) error { +func handle_mx_recv_conn(ctx context.Context, net_conn net.Conn) error { session := mx_recv_session{ net_conn: net_conn, + ctx: ctx, } return session.handle() } -- cgit v1.2.3