From: adam Date: Thu, 5 Aug 2004 23:24:33 +0000 (+0000) Subject: preliminary authentication support X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=a5377dcf386928b65abbf92f64e9d5954474da9b;p=org.ibex.mail.git preliminary authentication support darcs-hash:20040805232433-5007d-8cf9dd17cffc0cb3064bb890f040d6a5bf0eed6b.gz --- diff --git a/src/org/ibex/mail/Main.java b/src/org/ibex/mail/Main.java index cdca5a0..edc22c0 100644 --- a/src/org/ibex/mail/Main.java +++ b/src/org/ibex/mail/Main.java @@ -12,11 +12,39 @@ import org.ibex.crypto.*; public class Main implements Listener { public void accept(Connection conn) { - Log.error(this, "connection port is " + conn.getLocalPort()); - if (conn.getLocalPort() == 25) { - new SMTP.Server().handleRequest(conn); - } else if (conn.getLocalPort() == 143) { - new IMAP.Listener().handleRequest(conn); + try { + if (conn.getLocalPort() == 25) new SMTP.Server().handleRequest(conn); + else if (conn.getLocalPort() == 143) new IMAP.Listener(auth).handleRequest(conn); + else if (conn.getLocalPort() == 119) new NNTP.Listener(auth).handleRequest(conn); + } finally { + conn.close(); + } + } + + private static final Auth auth = new Auth(); + private static class Auth implements Login { + final Mailbox root = FileBasedMailbox.getFileBasedMailbox(Mailbox.STORAGE_ROOT, true).slash("user", true); + public Account anonymous() { return null; } + public Account login(String user, String pass) { + if (!EtcPasswd.verify(user, pass)) return null; + return new Account(user, null, root.slash(user, true)){ + public Mailbox getMailbox(Class protocol) { + if (protocol == NNTP.class) { + final Mailbox arch = new MailmanArchives(); + return new Mailbox.Default() { + public void add(Message m) { throw new RuntimeException("not supported"); } + public void add(Message m, int i) { throw new RuntimeException("not supported"); } + public int uidValidity() { return 1; } + public Mailbox.Iterator iterator() { return null; } + public int uidNext() { return 0; } + public String[] children() { return new String[] { "us" }; } + public Mailbox slash(String name, boolean create) { return arch; } + }; + } else { + return super.getMailbox(protocol); + } + } + }; } } diff --git a/src/org/ibex/mail/protocol/IMAP.java b/src/org/ibex/mail/protocol/IMAP.java index 5b74005..8e2c1ed 100644 --- a/src/org/ibex/mail/protocol/IMAP.java +++ b/src/org/ibex/mail/protocol/IMAP.java @@ -76,7 +76,6 @@ public class IMAP { public void fetch(Query q, int spec, String[] headers, int start, int end, boolean uid); public void lsub(String start, String ref); public void list(String start, String ref); - public static interface Authenticator { public abstract Mailbox authenticate(String user, String pass); } public static class Exn extends MailException { public Exn(String s) { super(s); } } public static class Bad extends Exn { public Bad(String s) { super(s); } } public static class No extends Exn { public No(String s) { super(s); } } @@ -94,10 +93,10 @@ public class IMAP { Mailbox selected = null; Mailbox root = null; Mailbox selected() { if (selected == null) throw new Bad("no mailbox selected"); return selected; } - final Server.Authenticator auth; + final Login auth; final Client client; - public MailboxWrapper(Server.Authenticator auth, Client c) { this.auth=auth; this.client=c;} + public MailboxWrapper(Login auth, Client c) { this.auth=auth; this.client=c;} private Mailbox mailbox(String name, boolean create) { if (name.equalsIgnoreCase("inbox")) return inbox; @@ -151,7 +150,9 @@ public class IMAP { for(Mailbox.Iterator it=selected().iterator(q);it.next();) to.add(it.cur(), it.flags() | Mailbox.Flag.RECENT); } public void login(String u, String p) { - if ((root = auth.authenticate(u,p)) == null) throw new No("Login failed."); + Account account = null; + if ((account = auth.login(u,p)) == null) throw new No("Login failed."); + root = account.getMailbox(IMAP.class); inbox = mailbox("INBOX", false); // FEATURE: ?? } public void unselect() { selected = null; } @@ -227,9 +228,10 @@ public class IMAP { String selectedName = null; Mailbox inbox = null, root = null; Server api; + Login auth = null; Parser parser = null; Connection conn = null; - public Listener() { } + public Listener(Login auth) { this.auth = auth; } Parser.Token token() { return parser.token(); } void println(String s) { conn.println(s); } void newline() { parser.newline(); } @@ -237,7 +239,7 @@ public class IMAP { public void handleRequest(Connection conn) { this.conn = conn; parser = new Parser(conn); - api = new IMAP.MailboxWrapper(new BogusAuthenticator(), this); + api = new IMAP.MailboxWrapper(auth, this); conn.setTimeout(30 * 60 * 1000); println("* OK " + conn.vhost + " " + IMAP.class.getName() + " IMAP4rev1 [RFC3501] v" + version + " server ready"); for(String tag = null;; newline()) try { @@ -790,26 +792,8 @@ public class IMAP { // Main ////////////////////////////////////////////////////////////////////////////// - /** simple listener for testing purposes */ - public static void main(String[] args) throws Exception { - ServerSocket ss = new ServerSocket(143); - for(;;) { - final Socket s = ss.accept(); - new Thread() { public void run() { try { - final Mailbox root = FileBasedMailbox.getFileBasedMailbox(Mailbox.STORAGE_ROOT+File.separatorChar+"imap", true); - new Listener(); - } catch (Exception e) { e.printStackTrace(); } } }.start(); - } - } - public static final int PEEK=0x1, BODYSTRUCTURE=0x2, ENVELOPE=0x4, FLAGS=0x8, INTERNALDATE=0x10, FIELDS=0x800, FIELDSNOT=0x1000, RFC822=0x20, RFC822TEXT=0x40, RFC822SIZE=0x80, HEADERNOT=0x100, UID=0x200, HEADER=0x400; - - public static class BogusAuthenticator implements IMAP.Server.Authenticator { - final Mailbox root = FileBasedMailbox.getFileBasedMailbox(Mailbox.STORAGE_ROOT, true).slash("user", true); - public Mailbox authenticate(String user, String pass) { - return EtcPasswd.verify(user, pass) ? root.slash(user, false) : null; } - } } diff --git a/src/org/ibex/mail/protocol/NNTP.java b/src/org/ibex/mail/protocol/NNTP.java index 7cf409c..862d375 100644 --- a/src/org/ibex/mail/protocol/NNTP.java +++ b/src/org/ibex/mail/protocol/NNTP.java @@ -96,13 +96,10 @@ public class NNTP { } public static class Listener implements Worker { - private Server api; + private Server api = null; + private Login login; private Connection conn; - public Listener(Server api) { this.api = api; } - public Listener() { - Mailbox root = FileBasedMailbox.getFileBasedMailbox("/var/org.ibex.mail/user/megacz/newmail/", true); - this.api = new MailboxWrapper(root); - } + public Listener(Login l) { this.login = l; } private void println(String s) { Log.warn("[nntp-write]", s); conn.println(s); } private void println() { Log.warn("[nntp-write]", ""); conn.println(); } @@ -127,10 +124,29 @@ public class NNTP { this.conn = conn; conn.setTimeout(30 * 60 * 1000); println("200 " + conn.vhost + " [" + NNTP.class.getName() + "]"); + String user = null; + String pass = null; + Account account = login.anonymous(); + this.api = account == null ? null : new MailboxWrapper(account.getMailbox(NNTP.class)); for(String line = conn.readln(); line != null; line = conn.readln()) try { Log.warn("[nntp-read]", line); StringTokenizer st = new StringTokenizer(line, " "); String command = st.nextToken().toUpperCase(); + if (command.equals("AUTHINFO")) { + String uop = st.nextToken(); + if (uop.equals("USER")) user = st.nextToken(); + else if (uop.equals("PASS")) pass = st.nextToken(); + // FIXME error here + } + if (this.api == null) { + if (user == null) { println("480 Authentication required"); continue; } + if (pass == null) { println("381 Password required"); continue; } + account = login.login(user, pass); + if (account == null) { println("502 Invalid"); continue; } + this.api = new MailboxWrapper(account.getMailbox(NNTP.class)); + println("281 Good to go"); + continue; + } if (command.equals("ARTICLE")) { article(st.hasMoreTokens() ? st.nextToken() : null, true, true); } else if (command.equals("HEAD")) { article(st.hasMoreTokens() ? st.nextToken() : null, true, false); } else if (command.equals("MODE")) { println("201 Hello, you can post.");