]> WPIA git - gigi.git/blobdiff - src/club/wpia/gigi/pages/LoginPage.java
add: ensure that for Org Administrator actions certificate login is used
[gigi.git] / src / club / wpia / gigi / pages / LoginPage.java
index 2af51cf71b937d31c9ebd1497985a6a74273e4a6..fccfea1d2e8db8f0d793af85d7ca930dd9618f33 100644 (file)
@@ -4,8 +4,9 @@ import static club.wpia.gigi.Gigi.*;
 
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.math.BigInteger;
 import java.security.cert.X509Certificate;
-import java.util.HashMap;
+import java.util.Date;
 import java.util.Map;
 
 import javax.servlet.http.HttpServletRequest;
@@ -15,6 +16,7 @@ import javax.servlet.http.HttpSession;
 import club.wpia.gigi.GigiApiException;
 import club.wpia.gigi.database.GigiPreparedStatement;
 import club.wpia.gigi.database.GigiResultSet;
+import club.wpia.gigi.dbObjects.Certificate;
 import club.wpia.gigi.dbObjects.CertificateOwner;
 import club.wpia.gigi.dbObjects.Group;
 import club.wpia.gigi.dbObjects.User;
@@ -25,8 +27,9 @@ import club.wpia.gigi.pages.main.RegisterPage;
 import club.wpia.gigi.util.AuthorizationContext;
 import club.wpia.gigi.util.PasswordHash;
 import club.wpia.gigi.util.RateLimit;
-import club.wpia.gigi.util.ServerConstants;
 import club.wpia.gigi.util.RateLimit.RateLimitException;
+import club.wpia.gigi.util.ServerConstants;
+import club.wpia.gigi.util.ServerConstants.Host;
 
 public class LoginPage extends Page {
 
@@ -62,17 +65,17 @@ public class LoginPage extends Page {
 
     @Override
     public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        if (req.getHeader("Host").equals(ServerConstants.getSecureHostNamePortSecure())) {
+        if (req.getHeader("Host").equals(ServerConstants.getHostNamePortSecure(Host.SECURE))) {
             resp.getWriter().println(getLanguage(req).getTranslation("Authentication with certificate failed. Try another certificate or use a password."));
         } else {
-            new LoginForm(req).output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
+            new LoginForm(req).output(resp.getWriter(), getLanguage(req), getDefaultVars(req));
         }
     }
 
     @Override
     public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
         if (Form.printFormErrors(req, resp.getWriter())) {
-            Form.getForm(req, LoginForm.class).output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
+            Form.getForm(req, LoginForm.class).output(resp.getWriter(), getLanguage(req), getDefaultVars(req));
         }
     }
 
@@ -119,24 +122,31 @@ public class LoginPage extends Page {
         try (GigiPreparedStatement ps = new GigiPreparedStatement("SELECT `password`, `id` FROM `users` WHERE `email`=? AND verified='1'")) {
             ps.setString(1, un);
             GigiResultSet rs = ps.executeQuery();
-            if (rs.next()) {
-                String dbHash = rs.getString(1);
-                String hash = PasswordHash.verifyHash(pw, dbHash);
-                if (hash != null) {
-                    if ( !hash.equals(dbHash)) {
-                        try (GigiPreparedStatement gps = new GigiPreparedStatement("UPDATE `users` SET `password`=? WHERE `email`=?")) {
-                            gps.setString(1, hash);
-                            gps.setString(2, un);
-                            gps.executeUpdate();
-                        }
+            if ( !rs.next()) {
+                throw new GigiApiException("Username and password didn't match.");
+            }
+
+            User user = User.getById(rs.getInt(2));
+            if (user == null) {
+                throw new GigiApiException("Username and password didn't match.");
+            }
+
+            String dbHash = rs.getString(1);
+            String hash = PasswordHash.verifyHash(pw, dbHash);
+            if (hash != null) {
+                if ( !hash.equals(dbHash)) {
+                    try (GigiPreparedStatement gps = new GigiPreparedStatement("UPDATE `users` SET `password`=? WHERE `email`=?")) {
+                        gps.setString(1, hash);
+                        gps.setString(2, un);
+                        gps.executeUpdate();
                     }
-                    loginSession(req, User.getById(rs.getInt(2)));
-                    req.getSession().setAttribute(LOGIN_METHOD, new TranslateCommand("Password"));
-                    return;
                 }
+
+                loginSession(req, user, false);
+                req.getSession().setAttribute(LOGIN_METHOD, new TranslateCommand("Password"));
+                return;
             }
         }
-        throw new GigiApiException("Username and password didn't match.");
     }
 
     public static User getUser(HttpServletRequest req) {
@@ -152,26 +162,26 @@ public class LoginPage extends Page {
     }
 
     private void tryAuthWithCertificate(HttpServletRequest req, X509Certificate x509Certificate) {
-        String serial = extractSerialFormCert(x509Certificate);
+        BigInteger serial = extractSerialFormCert(x509Certificate);
+        Certificate c = Certificate.getBySerial(serial);
         User user = fetchUserBySerial(serial);
         if (user == null) {
             return;
         }
-        loginSession(req, user);
+        if (c.getExpiryDate().before(new Date()) || c.getRevocationDate() != null || c.isLoginEnabled() == false) {
+            return;
+        }
+        loginSession(req, user, true);
         req.getSession().setAttribute(CERT_SERIAL, serial);
         req.getSession().setAttribute(CERT_ISSUER, x509Certificate.getIssuerDN());
         req.getSession().setAttribute(LOGIN_METHOD, new TranslateCommand("Certificate"));
     }
 
-    public static String extractSerialFormCert(X509Certificate x509Certificate) {
-        return x509Certificate.getSerialNumber().toString(16).toLowerCase();
+    public static BigInteger extractSerialFormCert(X509Certificate x509Certificate) {
+        return x509Certificate.getSerialNumber();
     }
 
-    public static User fetchUserBySerial(String serial) {
-        if ( !serial.matches("[a-f0-9]+")) {
-            throw new Error("serial malformed.");
-        }
-
+    public static User fetchUserBySerial(BigInteger serial) {
         CertificateOwner o = CertificateOwner.getByEnabledSerial(serial);
         if (o == null || !(o instanceof User)) {
             return null;
@@ -188,9 +198,9 @@ public class LoginPage extends Page {
         return uc;
     }
 
-    private static final Group LOGIN_BLOCKED = Group.BLOCKEDLOGIN;
+    private static final Group LOGIN_BLOCKED = Group.BLOCKED_LOGIN;
 
-    private void loginSession(HttpServletRequest req, User user) {
+    private void loginSession(HttpServletRequest req, User user, boolean isStronglyAuthenticated) {
         if (user.isInGroup(LOGIN_BLOCKED)) {
             return;
         }
@@ -199,7 +209,7 @@ public class LoginPage extends Page {
         HttpSession hs = req.getSession();
         hs.setAttribute(LOGGEDIN, true);
         hs.setAttribute(Language.SESSION_ATTRIB_NAME, user.getPreferredLocale());
-        hs.setAttribute(AUTH_CONTEXT, new AuthorizationContext(user, user));
+        hs.setAttribute(AUTH_CONTEXT, new AuthorizationContext(user, user, isStronglyAuthenticated));
     }
 
     @Override