From 4fc466a7d4d7bf71f2cdb62e11eeccfbffdbb274 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Felix=20D=C3=B6rre?= Date: Mon, 23 Jun 2014 15:09:47 +0200 Subject: [PATCH] Implement non-login pages. Add a test secure page. check signup data. --- src/org/cacert/gigi/Gigi.java | 88 ++------------ src/org/cacert/gigi/output/DateSelector.java | 6 + src/org/cacert/gigi/pages/LoginPage.java | 80 ++++++++++++- src/org/cacert/gigi/pages/MainPage.java | 8 +- src/org/cacert/gigi/pages/Page.java | 10 +- src/org/cacert/gigi/pages/TestSecure.java | 20 ++++ .../cacert/gigi/pages/main/RegisterPage.java | 14 ++- src/org/cacert/gigi/pages/main/Signup.java | 107 ++++++++++++++++-- 8 files changed, 231 insertions(+), 102 deletions(-) create mode 100644 src/org/cacert/gigi/pages/TestSecure.java diff --git a/src/org/cacert/gigi/Gigi.java b/src/org/cacert/gigi/Gigi.java index 6ca25d7d..ce0d46a5 100644 --- a/src/org/cacert/gigi/Gigi.java +++ b/src/org/cacert/gigi/Gigi.java @@ -5,10 +5,6 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; -import java.security.cert.X509Certificate; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; import java.util.Calendar; import java.util.HashMap; @@ -18,12 +14,11 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import org.cacert.gigi.database.DatabaseConnection; import org.cacert.gigi.pages.LoginPage; import org.cacert.gigi.pages.MainPage; import org.cacert.gigi.pages.Page; +import org.cacert.gigi.pages.TestSecure; import org.cacert.gigi.pages.main.RegisterPage; -import org.cacert.gigi.util.PasswordHash; import org.eclipse.jetty.util.log.Log; public class Gigi extends HttpServlet { @@ -37,6 +32,7 @@ public class Gigi extends HttpServlet { public void init() throws ServletException { pages.put("/login", new LoginPage("CACert - Login")); pages.put("/", new MainPage("CACert - Home")); + pages.put("/secure", new TestSecure()); pages.put(RegisterPage.PATH, new RegisterPage()); String templ = ""; try { @@ -53,30 +49,10 @@ public class Gigi extends HttpServlet { super.init(); } - @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - X509Certificate[] cert = (X509Certificate[]) req - .getAttribute("javax.servlet.request.X509Certificate"); HttpSession hs = req.getSession(); - if (hs.getAttribute(LOGGEDIN) == null) { - if (cert != null) { - tryAuthWithCertificate(req, cert[0]); - hs = req.getSession(); - } - } - if (hs.getAttribute("loggedin") != null - && req.getPathInfo().equals("/login")) { - resp.sendRedirect("/"); - return; - } - if (req.getMethod().equals("POST") && req.getPathInfo() != null - && req.getPathInfo().equals("/login")) { - authWithUnpw(req); - resp.sendRedirect("/"); - return; - } if (req.getPathInfo() != null && req.getPathInfo().equals("/logout")) { if (hs != null) { hs.setAttribute(LOGGEDIN, null); @@ -86,22 +62,17 @@ public class Gigi extends HttpServlet { return; } - if (hs.getAttribute("loggedin") == null - && !"/login".equals(req.getPathInfo())) { - System.out.println(req.getPathInfo()); - resp.sendRedirect("/login"); - return; - } if (pages.containsKey(req.getPathInfo())) { - String b0 = baseTemplate[0]; Page p = pages.get(req.getPathInfo()); + if (p.needsLogin() && hs.getAttribute("loggedin") == null) { + resp.sendRedirect("/login"); + return; + } + + String b0 = baseTemplate[0]; b0 = makeDynTempl(b0, p); resp.setContentType("text/html; charset=utf-8"); resp.getWriter().print(b0); - if (hs != null && hs.getAttribute(LOGGEDIN) != null) { - resp.getWriter().println( - "Hi " + ((User) hs.getAttribute(USER)).getFname()); - } if (req.getMethod().equals("POST")) { p.doPost(req, resp); } else { @@ -121,46 +92,5 @@ public class Gigi extends HttpServlet { in = in.replaceAll("\\$year\\$", year + ""); return in; } - private void authWithUnpw(HttpServletRequest req) { - String un = req.getParameter("username"); - String pw = req.getParameter("password"); - try { - PreparedStatement ps = DatabaseConnection.getInstance().prepare( - "SELECT `password`, `id` FROM `users` WHERE `email`=?"); - ps.setString(1, un); - ResultSet rs = ps.executeQuery(); - if (rs.next()) { - if (PasswordHash.verifyHash(pw, rs.getString(1))) { - HttpSession hs = req.getSession(); - hs.setAttribute(LOGGEDIN, true); - hs.setAttribute(USER, new User(rs.getInt(2))); - } - } - rs.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - } - private void tryAuthWithCertificate(HttpServletRequest req, - X509Certificate x509Certificate) { - String serial = x509Certificate.getSerialNumber().toString(16) - .toUpperCase(); - try { - PreparedStatement ps = DatabaseConnection - .getInstance() - .prepare( - "SELECT `memid` FROM `emailcerts` WHERE `serial`=? AND `disablelogin`='0' AND `revoked` = " - + "'0000-00-00 00:00:00'"); - ps.setString(1, serial); - ResultSet rs = ps.executeQuery(); - if (rs.next()) { - HttpSession hs = req.getSession(); - hs.setAttribute(LOGGEDIN, true); - hs.setAttribute(USER, new User(rs.getInt(1))); - } - rs.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - } + } diff --git a/src/org/cacert/gigi/output/DateSelector.java b/src/org/cacert/gigi/output/DateSelector.java index 782e6127..ba39b342 100644 --- a/src/org/cacert/gigi/output/DateSelector.java +++ b/src/org/cacert/gigi/output/DateSelector.java @@ -50,4 +50,10 @@ public class DateSelector implements Outputable { } out.print("\" size=\"4\" autocomplete=\"off\">"); } + public boolean isValid() { + if (!(1900 < year && 1 <= month && month <= 12 && 1 <= day && day <= 32)) { + return false; + } + return true; // TODO checkdate + } } diff --git a/src/org/cacert/gigi/pages/LoginPage.java b/src/org/cacert/gigi/pages/LoginPage.java index fe04cd46..134a0898 100644 --- a/src/org/cacert/gigi/pages/LoginPage.java +++ b/src/org/cacert/gigi/pages/LoginPage.java @@ -1,9 +1,21 @@ package org.cacert.gigi.pages; +import static org.cacert.gigi.Gigi.LOGGEDIN; +import static org.cacert.gigi.Gigi.USER; + import java.io.IOException; +import java.security.cert.X509Certificate; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; -import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.cacert.gigi.User; +import org.cacert.gigi.database.DatabaseConnection; +import org.cacert.gigi.util.PasswordHash; public class LoginPage extends Page { public LoginPage(String title) { @@ -11,13 +23,75 @@ public class LoginPage extends Page { } @Override - public void doGet(HttpServletRequest req, ServletResponse resp) + public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + HttpSession hs = req.getSession(); + if (hs.getAttribute("loggedin") == null) { + X509Certificate[] cert = (X509Certificate[]) req + .getAttribute("javax.servlet.request.X509Certificate"); + if (cert != null && cert[0] != null) { + tryAuthWithCertificate(req, cert[0]); + } + if (req.getMethod().equals("POST")) { + tryAuthWithUnpw(req); + } + } + + if (hs.getAttribute("loggedin") != null) { // Redir from login + resp.sendRedirect("/"); + return; + } + resp.getWriter() .println( "
" + "" + "
"); } - + @Override + public boolean needsLogin() { + return false; + } + private void tryAuthWithUnpw(HttpServletRequest req) { + String un = req.getParameter("username"); + String pw = req.getParameter("password"); + try { + PreparedStatement ps = DatabaseConnection.getInstance().prepare( + "SELECT `password`, `id` FROM `users` WHERE `email`=?"); + ps.setString(1, un); + ResultSet rs = ps.executeQuery(); + if (rs.next()) { + if (PasswordHash.verifyHash(pw, rs.getString(1))) { + HttpSession hs = req.getSession(); + hs.setAttribute(LOGGEDIN, true); + hs.setAttribute(USER, new User(rs.getInt(2))); + } + } + rs.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + private void tryAuthWithCertificate(HttpServletRequest req, + X509Certificate x509Certificate) { + String serial = x509Certificate.getSerialNumber().toString(16) + .toUpperCase(); + try { + PreparedStatement ps = DatabaseConnection + .getInstance() + .prepare( + "SELECT `memid` FROM `emailcerts` WHERE `serial`=? AND `disablelogin`='0' AND `revoked` = " + + "'0000-00-00 00:00:00'"); + ps.setString(1, serial); + ResultSet rs = ps.executeQuery(); + if (rs.next()) { + HttpSession hs = req.getSession(); + hs.setAttribute(LOGGEDIN, true); + hs.setAttribute(USER, new User(rs.getInt(1))); + } + rs.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } } diff --git a/src/org/cacert/gigi/pages/MainPage.java b/src/org/cacert/gigi/pages/MainPage.java index 3da5a0bf..adeaa802 100644 --- a/src/org/cacert/gigi/pages/MainPage.java +++ b/src/org/cacert/gigi/pages/MainPage.java @@ -2,8 +2,8 @@ package org.cacert.gigi.pages; import java.io.IOException; -import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; public class MainPage extends Page { public MainPage(String title) { @@ -11,8 +11,12 @@ public class MainPage extends Page { } @Override - public void doGet(HttpServletRequest req, ServletResponse resp) + public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { resp.getWriter().println("Access granted."); } + @Override + public boolean needsLogin() { + return false; + } } diff --git a/src/org/cacert/gigi/pages/Page.java b/src/org/cacert/gigi/pages/Page.java index cfc58d7a..7b59f9f1 100644 --- a/src/org/cacert/gigi/pages/Page.java +++ b/src/org/cacert/gigi/pages/Page.java @@ -3,8 +3,8 @@ package org.cacert.gigi.pages; import java.io.IOException; import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import org.cacert.gigi.Language; @@ -15,10 +15,10 @@ public abstract class Page { this.title = title; } - public abstract void doGet(HttpServletRequest req, ServletResponse resp) + public abstract void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException; - public void doPost(HttpServletRequest req, ServletResponse resp) + public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { doGet(req, resp); } @@ -38,6 +38,8 @@ public abstract class Page { Language l = getLanguage(req); return l.getTranslation(string); } - + public boolean needsLogin() { + return true; + } } diff --git a/src/org/cacert/gigi/pages/TestSecure.java b/src/org/cacert/gigi/pages/TestSecure.java new file mode 100644 index 00000000..e3d2f3cb --- /dev/null +++ b/src/org/cacert/gigi/pages/TestSecure.java @@ -0,0 +1,20 @@ +package org.cacert.gigi.pages; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class TestSecure extends Page { + + public TestSecure() { + super("Secure testpage"); + } + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse resp) + throws IOException { + resp.getWriter().println("This page is secure."); + } + +} diff --git a/src/org/cacert/gigi/pages/main/RegisterPage.java b/src/org/cacert/gigi/pages/main/RegisterPage.java index 6505c625..502f979d 100644 --- a/src/org/cacert/gigi/pages/main/RegisterPage.java +++ b/src/org/cacert/gigi/pages/main/RegisterPage.java @@ -6,8 +6,8 @@ import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.util.HashMap; -import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.cacert.gigi.output.Template; @@ -30,12 +30,12 @@ public class RegisterPage extends Page { } @Override - public void doGet(HttpServletRequest req, ServletResponse resp) + public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { PrintWriter out = resp.getWriter(); t.output(out, getLanguage(req), new HashMap()); Signup s = getForm(req); - s.writeForm(out, req); + s.writeForm(out, getLanguage(req)); } public Signup getForm(HttpServletRequest req) { HttpSession hs = req.getSession(); @@ -48,11 +48,15 @@ public class RegisterPage extends Page { } @Override - public void doPost(HttpServletRequest req, ServletResponse resp) + public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { Signup s = getForm(req); - s.update(req); + s.submit(resp.getWriter(), req); super.doPost(req, resp); } + @Override + public boolean needsLogin() { + return false; + } } diff --git a/src/org/cacert/gigi/pages/main/Signup.java b/src/org/cacert/gigi/pages/main/Signup.java index c1c47c56..007a58a6 100644 --- a/src/org/cacert/gigi/pages/main/Signup.java +++ b/src/org/cacert/gigi/pages/main/Signup.java @@ -3,12 +3,17 @@ package org.cacert.gigi.pages.main; import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.Date; import java.util.HashMap; import javax.servlet.ServletRequest; +import org.cacert.gigi.Language; import org.cacert.gigi.User; +import org.cacert.gigi.database.DatabaseConnection; import org.cacert.gigi.output.DateSelector; import org.cacert.gigi.output.Template; import org.cacert.gigi.pages.Page; @@ -17,6 +22,7 @@ import org.cacert.gigi.util.HTMLEncoder; public class Signup { User buildup = new User(); String password; + String password2; Template t; boolean general = true, country = true, regional = true, radius = true; public Signup() { @@ -35,7 +41,7 @@ public class Signup { } DateSelector myDoB = new DateSelector("day", "month", "year"); - public void writeForm(PrintWriter out, ServletRequest req) { + public void writeForm(PrintWriter out, Language l) { HashMap vars = new HashMap(); vars.put("fname", HTMLEncoder.encodeHTML(buildup.getFname())); vars.put("mname", HTMLEncoder.encodeHTML(buildup.getMname())); @@ -50,20 +56,103 @@ public class Signup { vars.put( "helpOnNames", String.format( - Page.translate(req, "Help on Names %sin the wiki%s"), + l.getTranslation("Help on Names %sin the wiki%s"), "", "")); - t.output(out, Page.getLanguage(req), vars); + t.output(out, l, vars); } - public void update(ServletRequest r) { - buildup.setFname(r.getParameter("fname")); - buildup.setLname(r.getParameter("lname")); - buildup.setMname(r.getParameter("mname")); - buildup.setSuffix(r.getParameter("suffix")); - buildup.setEmail(r.getParameter("email")); + private void update(ServletRequest r) { + if (r.getParameter("fname") != null) { + buildup.setFname(r.getParameter("fname")); + } + if (r.getParameter("lname") != null) { + buildup.setLname(r.getParameter("lname")); + } + if (r.getParameter("mname") != null) { + buildup.setMname(r.getParameter("mname")); + } + if (r.getParameter("suffix") != null) { + buildup.setSuffix(r.getParameter("suffix")); + } + if (r.getParameter("email") != null) { + buildup.setEmail(r.getParameter("email")); + } general = "1".equals(r.getParameter("general")); country = "1".equals(r.getParameter("country")); regional = "1".equals(r.getParameter("regional")); radius = "1".equals(r.getParameter("radius")); } + + public boolean submit(PrintWriter out, ServletRequest req) { + update(req); + boolean failed = false; + out.println("
"); + if (buildup.getFname().equals("") || buildup.getLname().equals("")) { + outputError(out, req, "First and/or last names were blank."); + failed = true; + } + if (!myDoB.isValid()) { + outputError(out, req, "Invalid date of birth"); + failed = true; + } + if (buildup.getEmail().equals("")) { + outputError(out, req, "Email Address was blank"); + failed = true; + } + String pw1 = req.getParameter("pword1"); + String pw2 = req.getParameter("pword2"); + if (pw1 == null || pw1.equals("")) { + outputError(out, req, "Pass Phrases were blank"); + failed = true; + } else if (!pw1.equals(pw2)) { + outputError(out, req, "Pass Phrases don't match"); + failed = true; + } + // TODO check password strength + try { + PreparedStatement q1 = DatabaseConnection.getInstance().prepare( + "select * from `email` where `email`=? and `deleted`=0"); + PreparedStatement q2 = DatabaseConnection.getInstance().prepare( + "select * from `users` where `email`=? and `deleted`=0"); + q1.setString(1, buildup.getEmail()); + q2.setString(1, buildup.getEmail()); + ResultSet r1 = q1.executeQuery(); + ResultSet r2 = q2.executeQuery(); + if (r1.next() || r2.next()) { + outputError(out, req, + "This email address is currently valid in the system."); + failed = true; + } + r1.close(); + r2.close(); + PreparedStatement q3 = DatabaseConnection + .getInstance() + .prepare( + "select `domain` from `baddomains` where `domain`=RIGHT(?, LENGTH(`domain`))"); + q3.setString(1, buildup.getEmail()); + + ResultSet r3 = q3.executeQuery(); + if (r3.next()) { + String domain = r3.getString(1); + out.print("
"); + out.print(String.format( + Page.translate(req, + "We don't allow signups from people using email addresses from %s"), + domain)); + out.println("
"); + failed = true; + } + r3.close(); + } catch (SQLException e) { + e.printStackTrace(); + failed = true; + } + out.println("
"); + return failed; + } + private void outputError(PrintWriter out, ServletRequest req, String text) { + out.print("
"); + out.print(Page.translate(req, text)); + out.println("
"); + } } -- 2.39.2