Search in sources :

Example 1 with X509Metadata

use of com.gitblit.utils.X509Utils.X509Metadata in project gitblit by gitblit.

the class GitBlitServer method start.

/**
	 * Start Gitblit GO.
	 */
protected final void start(Params params) {
    final File baseFolder = getBaseFolder(params);
    FileSettings settings = params.FILESETTINGS;
    if (!StringUtils.isEmpty(params.settingsfile)) {
        if (new File(params.settingsfile).exists()) {
            settings = new FileSettings(params.settingsfile);
        }
    }
    if (params.dailyLogFile) {
        // Configure log4j for daily log file generation
        InputStream is = null;
        try {
            is = getClass().getResourceAsStream("/log4j.properties");
            Properties loggingProperties = new Properties();
            loggingProperties.load(is);
            loggingProperties.put("log4j.appender.R.File", new File(baseFolder, "logs/gitblit.log").getAbsolutePath());
            loggingProperties.put("log4j.rootCategory", "INFO, R");
            if (settings.getBoolean(Keys.web.debugMode, false)) {
                loggingProperties.put("log4j.logger.com.gitblit", "DEBUG");
            }
            PropertyConfigurator.configure(loggingProperties);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    logger = LoggerFactory.getLogger(GitBlitServer.class);
    logger.info("\n" + Constants.getASCIIArt());
    System.setProperty("java.awt.headless", "true");
    String osname = System.getProperty("os.name");
    String osversion = System.getProperty("os.version");
    logger.info("Running on " + osname + " (" + osversion + ")");
    QueuedThreadPool threadPool = new QueuedThreadPool();
    int maxThreads = settings.getInteger(Keys.server.threadPoolSize, 50);
    if (maxThreads > 0) {
        threadPool.setMaxThreads(maxThreads);
    }
    Server server = new Server(threadPool);
    server.setStopAtShutdown(true);
    // conditionally configure the https connector
    if (params.securePort > 0) {
        File certificatesConf = new File(baseFolder, X509Utils.CA_CONFIG);
        File serverKeyStore = new File(baseFolder, X509Utils.SERVER_KEY_STORE);
        File serverTrustStore = new File(baseFolder, X509Utils.SERVER_TRUST_STORE);
        File caRevocationList = new File(baseFolder, X509Utils.CA_REVOCATION_LIST);
        // generate CA & web certificates, create certificate stores
        X509Metadata metadata = new X509Metadata("localhost", params.storePassword);
        // set default certificate values from config file
        if (certificatesConf.exists()) {
            FileBasedConfig config = new FileBasedConfig(certificatesConf, FS.detect());
            try {
                config.load();
            } catch (Exception e) {
                logger.error("Error parsing " + certificatesConf, e);
            }
            NewCertificateConfig certificateConfig = NewCertificateConfig.KEY.parse(config);
            certificateConfig.update(metadata);
        }
        metadata.notAfter = new Date(System.currentTimeMillis() + 10 * TimeUtils.ONEYEAR);
        X509Utils.prepareX509Infrastructure(metadata, baseFolder, new X509Log() {

            @Override
            public void log(String message) {
                BufferedWriter writer = null;
                try {
                    writer = new BufferedWriter(new FileWriter(new File(baseFolder, X509Utils.CERTS + File.separator + "log.txt"), true));
                    writer.write(MessageFormat.format("{0,date,yyyy-MM-dd HH:mm}: {1}", new Date(), message));
                    writer.newLine();
                    writer.flush();
                } catch (Exception e) {
                    LoggerFactory.getLogger(GitblitAuthority.class).error("Failed to append log entry!", e);
                } finally {
                    if (writer != null) {
                        try {
                            writer.close();
                        } catch (IOException e) {
                        }
                    }
                }
            }
        });
        if (serverKeyStore.exists()) {
            /*
				 * HTTPS
				 */
            logger.info("Setting up HTTPS transport on port " + params.securePort);
            GitblitSslContextFactory factory = new GitblitSslContextFactory(params.alias, serverKeyStore, serverTrustStore, params.storePassword, caRevocationList);
            if (params.requireClientCertificates) {
                factory.setNeedClientAuth(true);
            } else {
                factory.setWantClientAuth(true);
            }
            ServerConnector connector = new ServerConnector(server, factory);
            connector.setSoLingerTime(-1);
            connector.setIdleTimeout(30000);
            connector.setPort(params.securePort);
            String bindInterface = settings.getString(Keys.server.httpsBindInterface, null);
            if (!StringUtils.isEmpty(bindInterface)) {
                logger.warn(MessageFormat.format("Binding HTTPS transport on port {0,number,0} to {1}", params.securePort, bindInterface));
                connector.setHost(bindInterface);
            }
            if (params.securePort < 1024 && !isWindows()) {
                logger.warn("Gitblit needs to run with ROOT permissions for ports < 1024!");
            }
            server.addConnector(connector);
        } else {
            logger.warn("Failed to find or load Keystore?");
            logger.warn("HTTPS transport DISABLED.");
        }
    }
    // conditionally configure the http transport
    if (params.port > 0) {
        /*
			 * HTTP
			 */
        logger.info("Setting up HTTP transport on port " + params.port);
        HttpConfiguration httpConfig = new HttpConfiguration();
        if (params.port > 0 && params.securePort > 0 && settings.getBoolean(Keys.server.redirectToHttpsPort, true)) {
            httpConfig.setSecureScheme("https");
            httpConfig.setSecurePort(params.securePort);
        }
        httpConfig.setSendServerVersion(false);
        httpConfig.setSendDateHeader(false);
        ServerConnector connector = new ServerConnector(server, new HttpConnectionFactory(httpConfig));
        connector.setSoLingerTime(-1);
        connector.setIdleTimeout(30000);
        connector.setPort(params.port);
        String bindInterface = settings.getString(Keys.server.httpBindInterface, null);
        if (!StringUtils.isEmpty(bindInterface)) {
            logger.warn(MessageFormat.format("Binding HTTP transport on port {0,number,0} to {1}", params.port, bindInterface));
            connector.setHost(bindInterface);
        }
        if (params.port < 1024 && !isWindows()) {
            logger.warn("Gitblit needs to run with ROOT permissions for ports < 1024!");
        }
        server.addConnector(connector);
    }
    // tempDir is where the embedded Gitblit web application is expanded and
    // where Jetty creates any necessary temporary files
    File tempDir = com.gitblit.utils.FileUtils.resolveParameter(Constants.baseFolder$, baseFolder, params.temp);
    if (tempDir.exists()) {
        try {
            FileUtils.delete(tempDir, FileUtils.RECURSIVE | FileUtils.RETRY);
        } catch (IOException x) {
            logger.warn("Failed to delete temp dir " + tempDir.getAbsolutePath(), x);
        }
    }
    if (!tempDir.mkdirs()) {
        logger.warn("Failed to create temp dir " + tempDir.getAbsolutePath());
    }
    // Get the execution path of this class
    // We use this to set the WAR path.
    ProtectionDomain protectionDomain = GitBlitServer.class.getProtectionDomain();
    URL location = protectionDomain.getCodeSource().getLocation();
    // Root WebApp Context
    WebAppContext rootContext = new WebAppContext();
    rootContext.setContextPath(settings.getString(Keys.server.contextPath, "/"));
    rootContext.setServer(server);
    rootContext.setWar(location.toExternalForm());
    rootContext.setTempDirectory(tempDir);
    // Set cookies HttpOnly so they are not accessible to JavaScript engines
    HashSessionManager sessionManager = new HashSessionManager();
    sessionManager.setHttpOnly(true);
    // Use secure cookies if only serving https
    sessionManager.setSecureRequestOnly((params.port <= 0 && params.securePort > 0) || (params.port > 0 && params.securePort > 0 && settings.getBoolean(Keys.server.redirectToHttpsPort, true)));
    rootContext.getSessionHandler().setSessionManager(sessionManager);
    // Ensure there is a defined User Service
    String realmUsers = params.userService;
    if (StringUtils.isEmpty(realmUsers)) {
        logger.error(MessageFormat.format("PLEASE SPECIFY {0}!!", Keys.realm.userService));
        return;
    }
    // Override settings from the command-line
    settings.overrideSetting(Keys.realm.userService, params.userService);
    settings.overrideSetting(Keys.git.repositoriesFolder, params.repositoriesFolder);
    settings.overrideSetting(Keys.git.daemonPort, params.gitPort);
    settings.overrideSetting(Keys.git.sshPort, params.sshPort);
    // Start up an in-memory LDAP server, if configured
    try {
        if (!StringUtils.isEmpty(params.ldapLdifFile)) {
            File ldifFile = new File(params.ldapLdifFile);
            if (ldifFile != null && ldifFile.exists()) {
                URI ldapUrl = new URI(settings.getRequiredString(Keys.realm.ldap.server));
                String firstLine = new Scanner(ldifFile).nextLine();
                String rootDN = firstLine.substring(4);
                String bindUserName = settings.getString(Keys.realm.ldap.username, "");
                String bindPassword = settings.getString(Keys.realm.ldap.password, "");
                // Get the port
                int port = ldapUrl.getPort();
                if (port == -1)
                    port = 389;
                InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(rootDN);
                config.addAdditionalBindCredentials(bindUserName, bindPassword);
                config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("default", port));
                config.setSchema(null);
                InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config);
                ds.importFromLDIF(true, new LDIFReader(ldifFile));
                ds.startListening();
                logger.info("LDAP Server started at ldap://localhost:" + port);
            }
        }
    } catch (Exception e) {
        // Completely optional, just show a warning
        logger.warn("Unable to start LDAP server", e);
    }
    // Set the server's contexts
    server.setHandler(rootContext);
    // redirect HTTP requests to HTTPS
    if (params.port > 0 && params.securePort > 0 && settings.getBoolean(Keys.server.redirectToHttpsPort, true)) {
        logger.info(String.format("Configuring automatic http(%1$s) -> https(%2$s) redirects", params.port, params.securePort));
        // Create the internal mechanisms to handle secure connections and redirects
        Constraint constraint = new Constraint();
        constraint.setDataConstraint(Constraint.DC_CONFIDENTIAL);
        ConstraintMapping cm = new ConstraintMapping();
        cm.setConstraint(constraint);
        cm.setPathSpec("/*");
        ConstraintSecurityHandler sh = new ConstraintSecurityHandler();
        sh.setConstraintMappings(new ConstraintMapping[] { cm });
        // Configure this context to use the Security Handler defined before
        rootContext.setHandler(sh);
    }
    // Setup the Gitblit context
    GitblitContext gitblit = newGitblit(settings, baseFolder);
    rootContext.addEventListener(gitblit);
    try {
        // start the shutdown monitor
        if (params.shutdownPort > 0) {
            Thread shutdownMonitor = new ShutdownMonitorThread(server, params);
            shutdownMonitor.start();
        }
        // start Jetty
        server.start();
        server.join();
    } catch (Exception e) {
        e.printStackTrace();
        System.exit(100);
    }
}
Also used : ProtectionDomain(java.security.ProtectionDomain) Scanner(java.util.Scanner) InMemoryDirectoryServer(com.unboundid.ldap.listener.InMemoryDirectoryServer) Server(org.eclipse.jetty.server.Server) HashSessionManager(org.eclipse.jetty.server.session.HashSessionManager) Constraint(org.eclipse.jetty.util.security.Constraint) X509Metadata(com.gitblit.utils.X509Utils.X509Metadata) FileWriter(java.io.FileWriter) InMemoryDirectoryServerConfig(com.unboundid.ldap.listener.InMemoryDirectoryServerConfig) HttpConfiguration(org.eclipse.jetty.server.HttpConfiguration) Properties(java.util.Properties) URI(java.net.URI) URL(java.net.URL) BufferedWriter(java.io.BufferedWriter) ServerConnector(org.eclipse.jetty.server.ServerConnector) WebAppContext(org.eclipse.jetty.webapp.WebAppContext) QueuedThreadPool(org.eclipse.jetty.util.thread.QueuedThreadPool) ConstraintSecurityHandler(org.eclipse.jetty.security.ConstraintSecurityHandler) GitblitContext(com.gitblit.servlet.GitblitContext) GitblitAuthority(com.gitblit.authority.GitblitAuthority) FileBasedConfig(org.eclipse.jgit.storage.file.FileBasedConfig) NewCertificateConfig(com.gitblit.authority.NewCertificateConfig) ConstraintMapping(org.eclipse.jetty.security.ConstraintMapping) HttpConnectionFactory(org.eclipse.jetty.server.HttpConnectionFactory) InputStream(java.io.InputStream) InMemoryDirectoryServer(com.unboundid.ldap.listener.InMemoryDirectoryServer) X509Log(com.gitblit.utils.X509Utils.X509Log) IOException(java.io.IOException) CmdLineException(org.kohsuke.args4j.CmdLineException) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) Constraint(org.eclipse.jetty.util.security.Constraint) Date(java.util.Date) LDIFReader(com.unboundid.ldif.LDIFReader) File(java.io.File)

Example 2 with X509Metadata

use of com.gitblit.utils.X509Utils.X509Metadata in project gitblit by gitblit.

the class X509UtilsTest method testCertificateUserMapping.

@Test
public void testCertificateUserMapping() throws Exception {
    File storeFile = new File(folder, X509Utils.CA_KEY_STORE);
    PrivateKey caPrivateKey = X509Utils.getPrivateKey(X509Utils.CA_ALIAS, storeFile, caPassword);
    X509Certificate caCert = X509Utils.getCertificate(X509Utils.CA_ALIAS, storeFile, caPassword);
    X509Metadata userMetadata = new X509Metadata("james", "james");
    userMetadata.serverHostname = "www.myserver.com";
    userMetadata.userDisplayname = "James Moger";
    userMetadata.passwordHint = "your name";
    userMetadata.oids.put("C", "US");
    X509Certificate cert1 = X509Utils.newClientCertificate(userMetadata, caPrivateKey, caCert, storeFile.getParentFile());
    UserModel userModel1 = HttpUtils.getUserModelFromCertificate(cert1);
    assertEquals(userMetadata.commonName, userModel1.username);
    assertEquals(userMetadata.emailAddress, userModel1.emailAddress);
    assertEquals("C=US,O=Gitblit,OU=Gitblit,CN=james", cert1.getSubjectDN().getName());
    X509Certificate cert2 = X509Utils.newClientCertificate(userMetadata, caPrivateKey, caCert, storeFile.getParentFile());
    UserModel userModel2 = HttpUtils.getUserModelFromCertificate(cert2);
    assertEquals(userMetadata.commonName, userModel2.username);
    assertEquals(userMetadata.emailAddress, userModel2.emailAddress);
    assertEquals("C=US,O=Gitblit,OU=Gitblit,CN=james", cert2.getSubjectDN().getName());
    assertNotSame("Serial numbers are the same!", cert1.getSerialNumber().longValue(), cert2.getSerialNumber().longValue());
}
Also used : UserModel(com.gitblit.models.UserModel) PrivateKey(java.security.PrivateKey) X509Metadata(com.gitblit.utils.X509Utils.X509Metadata) File(java.io.File) X509Certificate(java.security.cert.X509Certificate) Test(org.junit.Test)

Example 3 with X509Metadata

use of com.gitblit.utils.X509Utils.X509Metadata in project gitblit by gitblit.

the class X509UtilsTest method testCertificateRevocation.

@Test
public void testCertificateRevocation() throws Exception {
    File storeFile = new File(folder, X509Utils.CA_KEY_STORE);
    PrivateKey caPrivateKey = X509Utils.getPrivateKey(X509Utils.CA_ALIAS, storeFile, caPassword);
    X509Certificate caCert = X509Utils.getCertificate(X509Utils.CA_ALIAS, storeFile, caPassword);
    X509Metadata userMetadata = new X509Metadata("james", "james");
    userMetadata.serverHostname = "www.myserver.com";
    userMetadata.userDisplayname = "James Moger";
    userMetadata.passwordHint = "your name";
    // generate a new client certificate
    X509Certificate cert1 = X509Utils.newClientCertificate(userMetadata, caPrivateKey, caCert, storeFile.getParentFile());
    // confirm this certificate IS NOT revoked
    File caRevocationList = new File(folder, X509Utils.CA_REVOCATION_LIST);
    assertFalse(X509Utils.isRevoked(cert1, caRevocationList));
    // revoke certificate and then confirm it IS revoked
    X509Utils.revoke(cert1, RevocationReason.ACompromise, caRevocationList, storeFile, caPassword, log);
    assertTrue(X509Utils.isRevoked(cert1, caRevocationList));
    // generate a second certificate
    X509Certificate cert2 = X509Utils.newClientCertificate(userMetadata, caPrivateKey, caCert, storeFile.getParentFile());
    // confirm second certificate IS NOT revoked
    assertTrue(X509Utils.isRevoked(cert1, caRevocationList));
    assertFalse(X509Utils.isRevoked(cert2, caRevocationList));
    // revoke second certificate and then confirm it IS revoked
    X509Utils.revoke(cert2, RevocationReason.ACompromise, caRevocationList, caPrivateKey, log);
    assertTrue(X509Utils.isRevoked(cert1, caRevocationList));
    assertTrue(X509Utils.isRevoked(cert2, caRevocationList));
    // generate a third certificate
    X509Certificate cert3 = X509Utils.newClientCertificate(userMetadata, caPrivateKey, caCert, storeFile.getParentFile());
    // confirm third certificate IS NOT revoked
    assertTrue(X509Utils.isRevoked(cert1, caRevocationList));
    assertTrue(X509Utils.isRevoked(cert2, caRevocationList));
    assertFalse(X509Utils.isRevoked(cert3, caRevocationList));
    // revoke third certificate and then confirm it IS revoked
    X509Utils.revoke(cert3, RevocationReason.ACompromise, caRevocationList, caPrivateKey, log);
    assertTrue(X509Utils.isRevoked(cert1, caRevocationList));
    assertTrue(X509Utils.isRevoked(cert2, caRevocationList));
    assertTrue(X509Utils.isRevoked(cert3, caRevocationList));
}
Also used : PrivateKey(java.security.PrivateKey) X509Metadata(com.gitblit.utils.X509Utils.X509Metadata) File(java.io.File) X509Certificate(java.security.cert.X509Certificate) Test(org.junit.Test)

Example 4 with X509Metadata

use of com.gitblit.utils.X509Utils.X509Metadata in project gitblit by gitblit.

the class AuthenticationManager method authenticate.

/**
	 * Authenticate a user based on HTTP request parameters.
	 *
	 * Authentication by custom HTTP header, servlet container principal, X509Certificate, cookie,
	 * and finally BASIC header.
	 *
	 * @param httpRequest
	 * @param requiresCertificate
	 * @return a user object or null
	 */
@Override
public UserModel authenticate(HttpServletRequest httpRequest, boolean requiresCertificate) {
    // Check if this request has already been authenticated, and trust that instead of re-processing
    String reqAuthUser = (String) httpRequest.getAttribute(Constants.ATTRIB_AUTHUSER);
    if (!StringUtils.isEmpty(reqAuthUser)) {
        logger.debug("Called servlet authenticate when request is already authenticated.");
        return userManager.getUserModel(reqAuthUser);
    }
    // try to authenticate by servlet container principal
    if (!requiresCertificate) {
        Principal principal = httpRequest.getUserPrincipal();
        if (principal != null) {
            String username = principal.getName();
            if (!StringUtils.isEmpty(username)) {
                boolean internalAccount = userManager.isInternalAccount(username);
                UserModel user = userManager.getUserModel(username);
                if (user != null) {
                    // existing user
                    flagRequest(httpRequest, AuthenticationType.CONTAINER, user.username);
                    logger.debug(MessageFormat.format("{0} authenticated by servlet container principal from {1}", user.username, httpRequest.getRemoteAddr()));
                    return validateAuthentication(user, AuthenticationType.CONTAINER);
                } else if (settings.getBoolean(Keys.realm.container.autoCreateAccounts, false) && !internalAccount) {
                    // auto-create user from an authenticated container principal
                    user = new UserModel(username.toLowerCase());
                    user.displayName = username;
                    user.password = Constants.EXTERNAL_ACCOUNT;
                    user.accountType = AccountType.CONTAINER;
                    // Try to extract user's informations for the session
                    // it uses "realm.container.autoAccounts.*" as the attribute name to look for
                    HttpSession session = httpRequest.getSession();
                    String emailAddress = resolveAttribute(session, Keys.realm.container.autoAccounts.emailAddress);
                    if (emailAddress != null) {
                        user.emailAddress = emailAddress;
                    }
                    String displayName = resolveAttribute(session, Keys.realm.container.autoAccounts.displayName);
                    if (displayName != null) {
                        user.displayName = displayName;
                    }
                    String userLocale = resolveAttribute(session, Keys.realm.container.autoAccounts.locale);
                    if (userLocale != null) {
                        user.getPreferences().setLocale(userLocale);
                    }
                    String adminRole = settings.getString(Keys.realm.container.autoAccounts.adminRole, null);
                    if (adminRole != null && !adminRole.isEmpty()) {
                        if (httpRequest.isUserInRole(adminRole)) {
                            user.canAdmin = true;
                        }
                    }
                    userManager.updateUserModel(user);
                    flagRequest(httpRequest, AuthenticationType.CONTAINER, user.username);
                    logger.debug(MessageFormat.format("{0} authenticated and created by servlet container principal from {1}", user.username, httpRequest.getRemoteAddr()));
                    return validateAuthentication(user, AuthenticationType.CONTAINER);
                } else if (!internalAccount) {
                    logger.warn(MessageFormat.format("Failed to find UserModel for {0}, attempted servlet container authentication from {1}", principal.getName(), httpRequest.getRemoteAddr()));
                }
            }
        }
    }
    // try to authenticate by certificate
    boolean checkValidity = settings.getBoolean(Keys.git.enforceCertificateValidity, true);
    String[] oids = settings.getStrings(Keys.git.certificateUsernameOIDs).toArray(new String[0]);
    UserModel model = HttpUtils.getUserModelFromCertificate(httpRequest, checkValidity, oids);
    if (model != null) {
        // grab real user model and preserve certificate serial number
        UserModel user = userManager.getUserModel(model.username);
        X509Metadata metadata = HttpUtils.getCertificateMetadata(httpRequest);
        if (user != null) {
            flagRequest(httpRequest, AuthenticationType.CERTIFICATE, user.username);
            logger.debug(MessageFormat.format("{0} authenticated by client certificate {1} from {2}", user.username, metadata.serialNumber, httpRequest.getRemoteAddr()));
            return validateAuthentication(user, AuthenticationType.CERTIFICATE);
        } else {
            logger.warn(MessageFormat.format("Failed to find UserModel for {0}, attempted client certificate ({1}) authentication from {2}", model.username, metadata.serialNumber, httpRequest.getRemoteAddr()));
        }
    }
    if (requiresCertificate) {
        // caller requires client certificate authentication (e.g. git servlet)
        return null;
    }
    UserModel user = null;
    // try to authenticate by cookie
    String cookie = getCookie(httpRequest);
    if (!StringUtils.isEmpty(cookie)) {
        user = userManager.getUserModel(cookie.toCharArray());
        if (user != null) {
            flagRequest(httpRequest, AuthenticationType.COOKIE, user.username);
            logger.debug(MessageFormat.format("{0} authenticated by cookie from {1}", user.username, httpRequest.getRemoteAddr()));
            return validateAuthentication(user, AuthenticationType.COOKIE);
        }
    }
    // try to authenticate by BASIC
    final String authorization = httpRequest.getHeader("Authorization");
    if (authorization != null && authorization.startsWith("Basic")) {
        // Authorization: Basic base64credentials
        String base64Credentials = authorization.substring("Basic".length()).trim();
        String credentials = new String(Base64.decode(base64Credentials), Charset.forName("UTF-8"));
        // credentials = username:password
        final String[] values = credentials.split(":", 2);
        if (values.length == 2) {
            String username = values[0];
            char[] password = values[1].toCharArray();
            user = authenticate(username, password, httpRequest.getRemoteAddr());
            if (user != null) {
                flagRequest(httpRequest, AuthenticationType.CREDENTIALS, user.username);
                logger.debug(MessageFormat.format("{0} authenticated by BASIC request header from {1}", user.username, httpRequest.getRemoteAddr()));
                return validateAuthentication(user, AuthenticationType.CREDENTIALS);
            }
        }
    }
    // Check each configured AuthenticationProvider
    for (AuthenticationProvider ap : authenticationProviders) {
        UserModel authedUser = ap.authenticate(httpRequest);
        if (null != authedUser) {
            flagRequest(httpRequest, ap.getAuthenticationType(), authedUser.username);
            logger.debug(MessageFormat.format("{0} authenticated by {1} from {2} for {3}", authedUser.username, ap.getServiceName(), httpRequest.getRemoteAddr(), httpRequest.getPathInfo()));
            return validateAuthentication(authedUser, ap.getAuthenticationType());
        }
    }
    return null;
}
Also used : UserModel(com.gitblit.models.UserModel) HttpSession(javax.servlet.http.HttpSession) X509Metadata(com.gitblit.utils.X509Utils.X509Metadata) UsernamePasswordAuthenticationProvider(com.gitblit.auth.AuthenticationProvider.UsernamePasswordAuthenticationProvider) AuthenticationProvider(com.gitblit.auth.AuthenticationProvider) Principal(java.security.Principal)

Example 5 with X509Metadata

use of com.gitblit.utils.X509Utils.X509Metadata in project gitblit by gitblit.

the class GitblitAuthority method getUI.

private Container getUI() {
    userCertificatePanel = new UserCertificatePanel(this) {

        private static final long serialVersionUID = 1L;

        @Override
        public Insets getInsets() {
            return Utils.INSETS;
        }

        @Override
        public boolean isAllowEmail() {
            return mail.isReady();
        }

        @Override
        public Date getDefaultExpiration() {
            Calendar c = Calendar.getInstance();
            c.add(Calendar.DATE, defaultDuration);
            c.set(Calendar.HOUR_OF_DAY, 0);
            c.set(Calendar.MINUTE, 0);
            c.set(Calendar.SECOND, 0);
            c.set(Calendar.MILLISECOND, 0);
            return c.getTime();
        }

        @Override
        public boolean saveUser(String username, UserCertificateModel ucm) {
            return userService.updateUserModel(username, ucm.user);
        }

        @Override
        public boolean newCertificate(UserCertificateModel ucm, X509Metadata metadata, boolean sendEmail) {
            if (!prepareX509Infrastructure()) {
                return false;
            }
            Date notAfter = metadata.notAfter;
            setMetadataDefaults(metadata);
            metadata.notAfter = notAfter;
            // set user's specified OID values
            UserModel user = ucm.user;
            if (!StringUtils.isEmpty(user.organizationalUnit)) {
                metadata.oids.put("OU", user.organizationalUnit);
            }
            if (!StringUtils.isEmpty(user.organization)) {
                metadata.oids.put("O", user.organization);
            }
            if (!StringUtils.isEmpty(user.locality)) {
                metadata.oids.put("L", user.locality);
            }
            if (!StringUtils.isEmpty(user.stateProvince)) {
                metadata.oids.put("ST", user.stateProvince);
            }
            if (!StringUtils.isEmpty(user.countryCode)) {
                metadata.oids.put("C", user.countryCode);
            }
            File caKeystoreFile = new File(folder, X509Utils.CA_KEY_STORE);
            File zip = X509Utils.newClientBundle(user, metadata, caKeystoreFile, caKeystorePassword, GitblitAuthority.this);
            // save latest expiration date
            if (ucm.expires == null || metadata.notAfter.before(ucm.expires)) {
                ucm.expires = metadata.notAfter;
            }
            updateAuthorityConfig(ucm);
            // refresh user
            ucm.certs = null;
            int selectedIndex = table.getSelectedRow();
            tableModel.fireTableDataChanged();
            table.getSelectionModel().setSelectionInterval(selectedIndex, selectedIndex);
            if (sendEmail) {
                sendEmail(user, metadata, zip);
            }
            return true;
        }

        @Override
        public boolean revoke(UserCertificateModel ucm, X509Certificate cert, RevocationReason reason) {
            if (!prepareX509Infrastructure()) {
                return false;
            }
            File caRevocationList = new File(folder, X509Utils.CA_REVOCATION_LIST);
            File caKeystoreFile = new File(folder, X509Utils.CA_KEY_STORE);
            if (X509Utils.revoke(cert, reason, caRevocationList, caKeystoreFile, caKeystorePassword, GitblitAuthority.this)) {
                File certificatesConfigFile = new File(folder, X509Utils.CA_CONFIG);
                FileBasedConfig config = new FileBasedConfig(certificatesConfigFile, FS.detect());
                if (certificatesConfigFile.exists()) {
                    try {
                        config.load();
                    } catch (Exception e) {
                        Utils.showException(GitblitAuthority.this, e);
                    }
                }
                // add serial to revoked list
                ucm.revoke(cert.getSerialNumber(), reason);
                ucm.update(config);
                try {
                    config.save();
                } catch (Exception e) {
                    Utils.showException(GitblitAuthority.this, e);
                }
                // refresh user
                ucm.certs = null;
                int modelIndex = table.convertRowIndexToModel(table.getSelectedRow());
                tableModel.fireTableDataChanged();
                table.getSelectionModel().setSelectionInterval(modelIndex, modelIndex);
                return true;
            }
            return false;
        }
    };
    table = Utils.newTable(tableModel, Utils.DATE_FORMAT);
    table.setRowSorter(defaultSorter);
    table.setDefaultRenderer(CertificateStatus.class, new CertificateStatusRenderer());
    table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

        @Override
        public void valueChanged(ListSelectionEvent e) {
            if (e.getValueIsAdjusting()) {
                return;
            }
            int row = table.getSelectedRow();
            if (row < 0) {
                return;
            }
            int modelIndex = table.convertRowIndexToModel(row);
            UserCertificateModel ucm = tableModel.get(modelIndex);
            if (ucm.certs == null) {
                ucm.certs = findCerts(folder, ucm.user.username);
            }
            userCertificatePanel.setUserCertificateModel(ucm);
        }
    });
    JPanel usersPanel = new JPanel(new BorderLayout()) {

        private static final long serialVersionUID = 1L;

        @Override
        public Insets getInsets() {
            return Utils.INSETS;
        }
    };
    usersPanel.add(new HeaderPanel(Translation.get("gb.users"), "users_16x16.png"), BorderLayout.NORTH);
    usersPanel.add(new JScrollPane(table), BorderLayout.CENTER);
    usersPanel.setMinimumSize(new Dimension(400, 10));
    certificateDefaultsButton = new JButton(new ImageIcon(getClass().getResource("/settings_16x16.png")));
    certificateDefaultsButton.setFocusable(false);
    certificateDefaultsButton.setToolTipText(Translation.get("gb.newCertificateDefaults"));
    certificateDefaultsButton.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            X509Metadata metadata = new X509Metadata("whocares", "whocares");
            File certificatesConfigFile = new File(folder, X509Utils.CA_CONFIG);
            FileBasedConfig config = new FileBasedConfig(certificatesConfigFile, FS.detect());
            NewCertificateConfig certificateConfig = null;
            if (certificatesConfigFile.exists()) {
                try {
                    config.load();
                } catch (Exception x) {
                    Utils.showException(GitblitAuthority.this, x);
                }
                certificateConfig = NewCertificateConfig.KEY.parse(config);
                certificateConfig.update(metadata);
            }
            InputVerifier verifier = new InputVerifier() {

                @Override
                public boolean verify(JComponent comp) {
                    boolean returnValue;
                    JTextField textField = (JTextField) comp;
                    try {
                        Integer.parseInt(textField.getText());
                        returnValue = true;
                    } catch (NumberFormatException e) {
                        returnValue = false;
                    }
                    return returnValue;
                }
            };
            JTextField siteNameTF = new JTextField(20);
            siteNameTF.setText(gitblitSettings.getString(Keys.web.siteName, "Gitblit"));
            JPanel siteNamePanel = Utils.newFieldPanel(Translation.get("gb.siteName"), siteNameTF, Translation.get("gb.siteNameDescription"));
            JTextField validityTF = new JTextField(4);
            validityTF.setInputVerifier(verifier);
            validityTF.setVerifyInputWhenFocusTarget(true);
            validityTF.setText("" + certificateConfig.duration);
            JPanel validityPanel = Utils.newFieldPanel(Translation.get("gb.validity"), validityTF, Translation.get("gb.duration.days").replace("{0}", "").trim());
            JPanel p1 = new JPanel(new GridLayout(0, 1, 5, 2));
            p1.add(siteNamePanel);
            p1.add(validityPanel);
            DefaultOidsPanel oids = new DefaultOidsPanel(metadata);
            JPanel panel = new JPanel(new BorderLayout());
            panel.add(p1, BorderLayout.NORTH);
            panel.add(oids, BorderLayout.CENTER);
            int result = JOptionPane.showConfirmDialog(GitblitAuthority.this, panel, Translation.get("gb.newCertificateDefaults"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, new ImageIcon(getClass().getResource("/settings_32x32.png")));
            if (result == JOptionPane.OK_OPTION) {
                try {
                    oids.update(metadata);
                    certificateConfig.duration = Integer.parseInt(validityTF.getText());
                    certificateConfig.store(config, metadata);
                    config.save();
                    Map<String, String> updates = new HashMap<String, String>();
                    updates.put(Keys.web.siteName, siteNameTF.getText());
                    gitblitSettings.saveSettings(updates);
                } catch (Exception e1) {
                    Utils.showException(GitblitAuthority.this, e1);
                }
            }
        }
    });
    newSSLCertificate = new JButton(new ImageIcon(getClass().getResource("/rosette_16x16.png")));
    newSSLCertificate.setFocusable(false);
    newSSLCertificate.setToolTipText(Translation.get("gb.newSSLCertificate"));
    newSSLCertificate.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            Date defaultExpiration = new Date(System.currentTimeMillis() + 10 * TimeUtils.ONEYEAR);
            NewSSLCertificateDialog dialog = new NewSSLCertificateDialog(GitblitAuthority.this, defaultExpiration);
            dialog.setModal(true);
            dialog.setVisible(true);
            if (dialog.isCanceled()) {
                return;
            }
            final Date expires = dialog.getExpiration();
            final String hostname = dialog.getHostname();
            final boolean serveCertificate = dialog.isServeCertificate();
            AuthorityWorker worker = new AuthorityWorker(GitblitAuthority.this) {

                @Override
                protected Boolean doRequest() throws IOException {
                    if (!prepareX509Infrastructure()) {
                        return false;
                    }
                    // read CA private key and certificate
                    File caKeystoreFile = new File(folder, X509Utils.CA_KEY_STORE);
                    PrivateKey caPrivateKey = X509Utils.getPrivateKey(X509Utils.CA_ALIAS, caKeystoreFile, caKeystorePassword);
                    X509Certificate caCert = X509Utils.getCertificate(X509Utils.CA_ALIAS, caKeystoreFile, caKeystorePassword);
                    // generate new SSL certificate
                    X509Metadata metadata = new X509Metadata(hostname, caKeystorePassword);
                    setMetadataDefaults(metadata);
                    metadata.notAfter = expires;
                    File serverKeystoreFile = new File(folder, X509Utils.SERVER_KEY_STORE);
                    X509Certificate cert = X509Utils.newSSLCertificate(metadata, caPrivateKey, caCert, serverKeystoreFile, GitblitAuthority.this);
                    boolean hasCert = cert != null;
                    if (hasCert && serveCertificate) {
                        // update Gitblit https connector alias
                        Map<String, String> updates = new HashMap<String, String>();
                        updates.put(Keys.server.certificateAlias, metadata.commonName);
                        gitblitSettings.saveSettings(updates);
                    }
                    return hasCert;
                }

                @Override
                protected void onSuccess() {
                    if (serveCertificate) {
                        JOptionPane.showMessageDialog(GitblitAuthority.this, MessageFormat.format(Translation.get("gb.sslCertificateGeneratedRestart"), hostname), Translation.get("gb.newSSLCertificate"), JOptionPane.INFORMATION_MESSAGE);
                    } else {
                        JOptionPane.showMessageDialog(GitblitAuthority.this, MessageFormat.format(Translation.get("gb.sslCertificateGenerated"), hostname), Translation.get("gb.newSSLCertificate"), JOptionPane.INFORMATION_MESSAGE);
                    }
                }
            };
            worker.execute();
        }
    });
    JButton emailBundle = new JButton(new ImageIcon(getClass().getResource("/mail_16x16.png")));
    emailBundle.setFocusable(false);
    emailBundle.setToolTipText(Translation.get("gb.emailCertificateBundle"));
    emailBundle.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            int row = table.getSelectedRow();
            if (row < 0) {
                return;
            }
            int modelIndex = table.convertRowIndexToModel(row);
            final UserCertificateModel ucm = tableModel.get(modelIndex);
            if (ArrayUtils.isEmpty(ucm.certs)) {
                JOptionPane.showMessageDialog(GitblitAuthority.this, MessageFormat.format(Translation.get("gb.pleaseGenerateClientCertificate"), ucm.user.getDisplayName()));
            }
            final File zip = new File(folder, X509Utils.CERTS + File.separator + ucm.user.username + File.separator + ucm.user.username + ".zip");
            if (!zip.exists()) {
                return;
            }
            AuthorityWorker worker = new AuthorityWorker(GitblitAuthority.this) {

                @Override
                protected Boolean doRequest() throws IOException {
                    X509Metadata metadata = new X509Metadata(ucm.user.username, "whocares");
                    metadata.serverHostname = gitblitSettings.getString(Keys.web.siteName, Constants.NAME);
                    if (StringUtils.isEmpty(metadata.serverHostname)) {
                        metadata.serverHostname = Constants.NAME;
                    }
                    metadata.userDisplayname = ucm.user.getDisplayName();
                    return sendEmail(ucm.user, metadata, zip);
                }

                @Override
                protected void onSuccess() {
                    JOptionPane.showMessageDialog(GitblitAuthority.this, MessageFormat.format(Translation.get("gb.clientCertificateBundleSent"), ucm.user.getDisplayName()));
                }
            };
            worker.execute();
        }
    });
    JButton logButton = new JButton(new ImageIcon(getClass().getResource("/script_16x16.png")));
    logButton.setFocusable(false);
    logButton.setToolTipText(Translation.get("gb.log"));
    logButton.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            File log = new File(folder, X509Utils.CERTS + File.separator + "log.txt");
            if (log.exists()) {
                String content = FileUtils.readContent(log, "\n");
                JTextArea textarea = new JTextArea(content);
                JScrollPane scrollPane = new JScrollPane(textarea);
                scrollPane.setPreferredSize(new Dimension(700, 400));
                JOptionPane.showMessageDialog(GitblitAuthority.this, scrollPane, log.getAbsolutePath(), JOptionPane.INFORMATION_MESSAGE);
            }
        }
    });
    final JTextField filterTextfield = new JTextField(15);
    filterTextfield.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            filterUsers(filterTextfield.getText());
        }
    });
    filterTextfield.addKeyListener(new KeyAdapter() {

        @Override
        public void keyReleased(KeyEvent e) {
            filterUsers(filterTextfield.getText());
        }
    });
    JToolBar buttonControls = new JToolBar(JToolBar.HORIZONTAL);
    buttonControls.setFloatable(false);
    buttonControls.add(certificateDefaultsButton);
    buttonControls.add(newSSLCertificate);
    buttonControls.add(emailBundle);
    buttonControls.add(logButton);
    JPanel userControls = new JPanel(new FlowLayout(FlowLayout.RIGHT, Utils.MARGIN, Utils.MARGIN));
    userControls.add(new JLabel(Translation.get("gb.filter")));
    userControls.add(filterTextfield);
    JPanel topPanel = new JPanel(new BorderLayout(0, 0));
    topPanel.add(buttonControls, BorderLayout.WEST);
    topPanel.add(userControls, BorderLayout.EAST);
    JPanel leftPanel = new JPanel(new BorderLayout());
    leftPanel.add(topPanel, BorderLayout.NORTH);
    leftPanel.add(usersPanel, BorderLayout.CENTER);
    userCertificatePanel.setMinimumSize(new Dimension(375, 10));
    JLabel statusLabel = new JLabel();
    statusLabel.setHorizontalAlignment(SwingConstants.RIGHT);
    if (X509Utils.unlimitedStrength) {
        statusLabel.setText("JCE Unlimited Strength Jurisdiction Policy");
    } else {
        statusLabel.setText("JCE Standard Encryption Policy");
    }
    JPanel root = new JPanel(new BorderLayout()) {

        private static final long serialVersionUID = 1L;

        @Override
        public Insets getInsets() {
            return Utils.INSETS;
        }
    };
    JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, userCertificatePanel);
    splitPane.setDividerLocation(1d);
    root.add(splitPane, BorderLayout.CENTER);
    root.add(statusLabel, BorderLayout.SOUTH);
    return root;
}
Also used : JPanel(javax.swing.JPanel) PrivateKey(java.security.PrivateKey) JTextArea(javax.swing.JTextArea) X509Metadata(com.gitblit.utils.X509Utils.X509Metadata) ActionEvent(java.awt.event.ActionEvent) KeyAdapter(java.awt.event.KeyAdapter) BorderLayout(java.awt.BorderLayout) X509Certificate(java.security.cert.X509Certificate) ListSelectionListener(javax.swing.event.ListSelectionListener) ActionListener(java.awt.event.ActionListener) JSplitPane(javax.swing.JSplitPane) File(java.io.File) Map(java.util.Map) HashMap(java.util.HashMap) ImageIcon(javax.swing.ImageIcon) Insets(java.awt.Insets) FlowLayout(java.awt.FlowLayout) ListSelectionEvent(javax.swing.event.ListSelectionEvent) JButton(javax.swing.JButton) JTextField(javax.swing.JTextField) UserModel(com.gitblit.models.UserModel) KeyEvent(java.awt.event.KeyEvent) GridLayout(java.awt.GridLayout) FileBasedConfig(org.eclipse.jgit.storage.file.FileBasedConfig) RevocationReason(com.gitblit.utils.X509Utils.RevocationReason) JScrollPane(javax.swing.JScrollPane) Calendar(java.util.Calendar) JComponent(javax.swing.JComponent) JLabel(javax.swing.JLabel) Dimension(java.awt.Dimension) IOException(java.io.IOException) JToolBar(javax.swing.JToolBar) InputVerifier(javax.swing.InputVerifier) Date(java.util.Date) ConfigInvalidException(org.eclipse.jgit.errors.ConfigInvalidException) IOException(java.io.IOException) HeaderPanel(com.gitblit.client.HeaderPanel)

Aggregations

X509Metadata (com.gitblit.utils.X509Utils.X509Metadata)9 File (java.io.File)5 UserModel (com.gitblit.models.UserModel)4 PrivateKey (java.security.PrivateKey)3 X509Certificate (java.security.cert.X509Certificate)3 Date (java.util.Date)3 Test (org.junit.Test)3 BorderLayout (java.awt.BorderLayout)2 IOException (java.io.IOException)2 FileBasedConfig (org.eclipse.jgit.storage.file.FileBasedConfig)2 AuthenticationProvider (com.gitblit.auth.AuthenticationProvider)1 UsernamePasswordAuthenticationProvider (com.gitblit.auth.AuthenticationProvider.UsernamePasswordAuthenticationProvider)1 GitblitAuthority (com.gitblit.authority.GitblitAuthority)1 NewCertificateConfig (com.gitblit.authority.NewCertificateConfig)1 HeaderPanel (com.gitblit.client.HeaderPanel)1 GitblitContext (com.gitblit.servlet.GitblitContext)1 RevocationReason (com.gitblit.utils.X509Utils.RevocationReason)1 X509Log (com.gitblit.utils.X509Utils.X509Log)1 InMemoryDirectoryServer (com.unboundid.ldap.listener.InMemoryDirectoryServer)1 InMemoryDirectoryServerConfig (com.unboundid.ldap.listener.InMemoryDirectoryServerConfig)1