<exclude name="federation.properties" />\r
<exclude name="openshift.mkd" />\r
<exclude name="authority.conf" />\r
+ <exclude name="*.tmpl" />\r
</fileset>\r
<fileset dir="${basedir}">\r
<include name="LICENSE" />\r
<mkdir dir="${project.deploy.dir}/certs"/>\r
<copy todir="${project.deploy.dir}/certs">\r
<fileset dir="${basedir}/distrib">\r
+ <include name="*.tmpl" />\r
<include name="authority.conf" />\r
</fileset>\r
</copy>\r
--- /dev/null
+********************************************************************************\r
+ Gitblit SSL Client Certificate for $serverHostname\r
+********************************************************************************\r
+\r
+ Hello $userDisplayname,\r
+\r
+ Your private key, public certificate, and the Gitblit Certificate Authority \r
+ certificate for $serverHostname are stored in $username.p12, a PKCS#12 certificate\r
+ store[1], and also in $username.pem, a PEM certificate store.\r
+\r
+ Both of these certificate stores are password-protected. \r
+ Password Hint: $storePasswordHint\r
+\r
+\r
+Git (All) Installation Instructions\r
+=============================================\r
+\r
+ The provided PEM file can be directly used by your git client.\r
+ \r
+ git config [--global] http.sslCert path/to/$username.pem\r
+ \r
+ The supplied PEM file is password-protected and you may be prompted for your\r
+ password multiple times during an exchange with Gitblit. If you desire a\r
+ password-less git client workflow then you will need to decrypt and export your\r
+ private key with OpenSSL[2] and then update your git config to use that key.\r
+ \r
+ openssl rsa -in path/to/$username.pem -out path/to/$username.key \r
+ git config [--global] http.sslKey path/to/$username.key\r
+\r
+ Obviously, you should protect access to any decrypted private key.\r
+ \r
+ NOTE:\r
+ Some older git clients may have trouble using the PEM file without explicitly\r
+ extracting the private key. This has been observed, for example, on Ubuntu 12.04\r
+ with git 1.7.9.5.\r
+\r
+\r
+Firefox (All) Installation Instructions\r
+=============================================\r
+\r
+ Firefox maintains it's own certificate store which is separate from the operating\r
+ system.\r
+\r
+ 1. Navigate to Options->Advanced->Encryption\r
+ 2. Click "View Certificates"\r
+ 3. Switch to the "Your Certificates" tab\r
+ 4. Click "Import..."\r
+ 5. Navigate your filesystem and select $username.p12\r
+ 6. At the password prompt enter the certificate store password\r
+ You have now imported your private key, public certificate, and the CA certificate\r
+ but now we must manually set the trust settings of the CA certificate.\r
+ 7. Switch to the "Authorities" tab\r
+ 8. Scroll down and find "Gitblit-> Gitblit Certificate Authority"\r
+ 9. Select it and click "Edit Trust..."\r
+ 10. Check "This certificate can identify websites" and click OK.\r
+\r
+\r
+Chrome/IE (Windows) Installation Instructions\r
+=============================================\r
+\r
+ On Windows, Chrome and IE share their certificate store so configuring one will\r
+ automatically apply for both.\r
+\r
+ IE\r
+ ------------------------------------\r
+ 1. Navigate to Internet Options->Content\r
+ 2. Click the "Certificates" button\r
+\r
+ Chrome\r
+ ------------------------------------\r
+ 1. Navigate to Settings->Show Advanced Settings->HTTP/SSL\r
+ 2. Click the "Manage Certificates..." button\r
+\r
+ Both (Windows)\r
+ ------------------------------------\r
+ 3. Switch to the "Personal" tab\r
+ 4. Click the "Import..." button\r
+ 5. Follow the Import Wizard instructions.\r
+ You will need to change the selected file filter when navigating to $username.p12\r
+ 6. At the password prompt enter the certificate store password\r
+ 7. Because both your personal certificate and the CA certifcate are stored in \r
+ $username.p12, you must choose "Automatically select the certificate store based on the type of certificate".\r
+ If you choose the default you will not install the CA certificate.\r
+\r
+\r
+Chrome (Linux) Installation Instructions\r
+=============================================\r
+ \r
+ On Linux, Chrome maintains it's own certificate store.\r
+ \r
+ 1. Navigate to Settings->Show Advanced Settings->HTTP/SSL\r
+ 2. Click the "Manage Certificates..." button\r
+ 3. Navigate your filesystem and select $username.p12\r
+ 4. At the password prompt enter the certificate store password\r
+ You have now imported your private key, public certificate, and the CA certificate\r
+ but now we must manually set the trust settings of the CA certificate.\r
+ 5. Switch to the "Authorities" tab\r
+ 6. Scroll down and find "Gitblit-> Gitblit Certificate Authority"\r
+ 7. Select it and click "Edit Trust..."\r
+ 8. Check "This certificate can identify websites" and click OK.\r
+\r
+\r
+Chrome/Safari (Mac OS X) Installation Instructions\r
+=============================================\r
+\r
+On Mac OS X, Chrome and Safari both use Keychain Access to store certificates\r
+so configuring one will automatically apply for both.\r
+\r
+ 1. Double-click $username.pem\r
+ 2. At the password prompt enter the certificate store password\r
+ You have now imported your private key, public certificate, and the CA certificate\r
+ but now we must manually set the trust settings of the CA certificate.\r
+ 3. Find the Gitblit Certificate Authority certificate, it should have a red\r
+ indicator meaning untrusted, and double-click it.\r
+ 4. Open the "Trust" disclosure triangle and change "When using this certificate"\r
+ to "Always Trust".\r
+ 5. Close the certificate view and enter your system password to save the changes\r
+ to your keychain. \r
+ \r
+ \r
+[1] PKCS#12 is one of the standard container formats for sharing private keys and\r
+ public certificates.\r
+[2] http://www.openssl.org\r
--- /dev/null
+ Hello $userDisplayname,\r
+\r
+ Your private key, public certificate, and the Gitblit Certificate Authority \r
+ certificate for $serverHostname are bundled together in the attached zip file.\r
+\r
+ There are also setup/installation instructions included in the zip for Git and\r
+ several major browsers to get you started.
\ No newline at end of file
--- /dev/null
+@java -cp gitblit.jar;"%CD%\ext\*" com.gitblit.authority.MakeClientCertificate\r
--- /dev/null
+#!/bin/sh
+java -cp gitblit.jar:$PWD/ext/* com.gitblit.authority.MakeClientCertificate
\r
private static final String EMAILADDRESS = "emailAddress";\r
\r
+ private static final String ORGANIZATIONALUNIT = "organizationalUnit";\r
+ \r
+ private static final String ORGANIZATION = "organization";\r
+ \r
+ private static final String LOCALITY = "locality";\r
+ \r
+ private static final String STATEPROVINCE = "stateProvince";\r
+ \r
+ private static final String COUNTRYCODE = "countryCode";\r
+ \r
private static final String COOKIE = "cookie";\r
\r
private static final String REPOSITORY = "repository";\r
if (!StringUtils.isEmpty(model.emailAddress)) {\r
config.setString(USER, model.username, EMAILADDRESS, model.emailAddress);\r
}\r
+ if (!StringUtils.isEmpty(model.organizationalUnit)) {\r
+ config.setString(USER, model.username, ORGANIZATIONALUNIT, model.organizationalUnit);\r
+ }\r
+ if (!StringUtils.isEmpty(model.organization)) {\r
+ config.setString(USER, model.username, ORGANIZATION, model.organization);\r
+ }\r
+ if (!StringUtils.isEmpty(model.locality)) {\r
+ config.setString(USER, model.username, LOCALITY, model.locality);\r
+ }\r
+ if (!StringUtils.isEmpty(model.stateProvince)) {\r
+ config.setString(USER, model.username, STATEPROVINCE, model.stateProvince);\r
+ }\r
+ if (!StringUtils.isEmpty(model.countryCode)) {\r
+ config.setString(USER, model.username, COUNTRYCODE, model.countryCode);\r
+ }\r
\r
// user roles\r
List<String> roles = new ArrayList<String>();\r
user.password = config.getString(USER, username, PASSWORD); \r
user.displayName = config.getString(USER, username, DISPLAYNAME);\r
user.emailAddress = config.getString(USER, username, EMAILADDRESS);\r
+ user.organizationalUnit = config.getString(USER, username, ORGANIZATIONALUNIT);\r
+ user.organization = config.getString(USER, username, ORGANIZATION);\r
+ user.locality = config.getString(USER, username, LOCALITY);\r
+ user.stateProvince = config.getString(USER, username, STATEPROVINCE);\r
+ user.countryCode = config.getString(USER, username, COUNTRYCODE);\r
user.cookie = config.getString(USER, username, COOKIE);\r
if (StringUtils.isEmpty(user.cookie) && !StringUtils.isEmpty(user.password)) {\r
user.cookie = StringUtils.getSHA1(user.username + user.password);\r
}\r
}\r
}\r
+ \r
+ public void sendNow(Message message) throws Exception {\r
+ Transport.send(message);\r
+ }\r
}\r
--- /dev/null
+/*\r
+ * Copyright 2012 gitblit.com.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package com.gitblit.authority;\r
+\r
+import java.io.File;\r
+import java.text.MessageFormat;\r
+import java.util.Date;\r
+\r
+import javax.activation.DataHandler;\r
+import javax.activation.FileDataSource;\r
+import javax.mail.Message;\r
+import javax.mail.Multipart;\r
+import javax.mail.internet.MimeBodyPart;\r
+import javax.mail.internet.MimeMultipart;\r
+\r
+import org.eclipse.jgit.storage.file.FileBasedConfig;\r
+import org.eclipse.jgit.util.FS;\r
+\r
+import com.beust.jcommander.JCommander;\r
+import com.beust.jcommander.Parameter;\r
+import com.beust.jcommander.ParameterException;\r
+import com.beust.jcommander.Parameters;\r
+import com.gitblit.ConfigUserService;\r
+import com.gitblit.Constants;\r
+import com.gitblit.FileSettings;\r
+import com.gitblit.IUserService;\r
+import com.gitblit.Keys;\r
+import com.gitblit.MailExecutor;\r
+import com.gitblit.models.UserModel;\r
+import com.gitblit.utils.StringUtils;\r
+import com.gitblit.utils.TimeUtils;\r
+import com.gitblit.utils.X509Utils;\r
+import com.gitblit.utils.X509Utils.X509Metadata;\r
+\r
+/**\r
+ * Utility class to generate self-signed certificates.\r
+ * \r
+ * @author James Moger\r
+ * \r
+ */\r
+public class MakeClientCertificate {\r
+\r
+ public static void main(String... args) throws Exception {\r
+ Params params = new Params();\r
+ JCommander jc = new JCommander(params);\r
+ try {\r
+ jc.parse(args);\r
+ } catch (ParameterException t) {\r
+ System.err.println(t.getMessage());\r
+ jc.usage();\r
+ System.exit(-1);\r
+ }\r
+\r
+ // Load the user list\r
+ String us = Params.FILESETTINGS.getString(Keys.realm.userService, "users.conf");\r
+ String ext = us.substring(us.lastIndexOf(".") + 1).toLowerCase();\r
+ IUserService service = null;\r
+ if (!ext.equals("conf") && !ext.equals("properties")) {\r
+ if (us.equals("com.gitblit.LdapUserService")) {\r
+ us = Params.FILESETTINGS.getString(Keys.realm.ldap.backingUserService, "users.conf"); \r
+ } else if (us.equals("com.gitblit.LdapUserService")) {\r
+ us = Params.FILESETTINGS.getString(Keys.realm.redmine.backingUserService, "users.conf");\r
+ }\r
+ }\r
+\r
+ if (us.endsWith(".conf")) {\r
+ service = new ConfigUserService(new File(us));\r
+ } else {\r
+ throw new RuntimeException("Unsupported user service: " + us);\r
+ }\r
+ \r
+ // Confirm the user exists\r
+ UserModel user = service.getUserModel(params.username);\r
+ if (user == null) {\r
+ System.out.println(MessageFormat.format("Failed to find user \"{0}\" in {1}", params.username, us));\r
+ System.exit(-1);\r
+ }\r
+ \r
+ File folder = new File(System.getProperty("user.dir"));\r
+ X509Metadata serverMetadata = new X509Metadata("localhost", params.storePassword); \r
+ X509Utils.prepareX509Infrastructure(serverMetadata, folder);\r
+ \r
+ File caStore = new File(folder, X509Utils.CA_KEY_STORE);\r
+ \r
+ X509Metadata clientMetadata = new X509Metadata(params.username, params.password);\r
+ clientMetadata.userDisplayname = user.getDisplayName();\r
+ clientMetadata.emailAddress = user.emailAddress;\r
+ clientMetadata.serverHostname = params.serverHostname;\r
+ clientMetadata.passwordHint = params.hint;\r
+ \r
+ UserCertificateModel ucm = null;\r
+ \r
+ // set default values from config file\r
+ File certificatesConfigFile = new File(folder, X509Utils.CA_CONFIG);\r
+ FileBasedConfig config = new FileBasedConfig(certificatesConfigFile, FS.detect());\r
+ if (certificatesConfigFile.exists()) {\r
+ config.load();\r
+ NewCertificateConfig certificateConfig = NewCertificateConfig.KEY.parse(config);\r
+ certificateConfig.update(clientMetadata);\r
+ \r
+ ucm = UserCertificateConfig.KEY.parse(config).getUserCertificateModel(params.username);\r
+ }\r
+ \r
+ // set user's specified OID values\r
+ if (!StringUtils.isEmpty(user.organizationalUnit)) {\r
+ clientMetadata.oids.put("OU", user.organizationalUnit);\r
+ }\r
+ if (!StringUtils.isEmpty(user.organization)) {\r
+ clientMetadata.oids.put("O", user.organization);\r
+ }\r
+ if (!StringUtils.isEmpty(user.locality)) {\r
+ clientMetadata.oids.put("L", user.locality);\r
+ }\r
+ if (!StringUtils.isEmpty(user.stateProvince)) {\r
+ clientMetadata.oids.put("ST", user.stateProvince);\r
+ }\r
+ if (!StringUtils.isEmpty(user.countryCode)) {\r
+ clientMetadata.oids.put("C", user.countryCode);\r
+ }\r
+\r
+ if (params.duration > 0) {\r
+ // overriding duration from command-line parameter\r
+ clientMetadata.notAfter = new Date(System.currentTimeMillis() + TimeUtils.ONEDAY * params.duration);\r
+ }\r
+\r
+ // generate zip bundle\r
+ File zip = X509Utils.newClientBundle(clientMetadata, caStore, params.storePassword); \r
+ \r
+ String indent = " ";\r
+ System.out.println(MessageFormat.format("Client certificate bundle generated for {0}", params.username));\r
+ System.out.print(indent);\r
+ System.out.println(zip);\r
+ \r
+ // update certificates.conf\r
+ if (ucm == null) {\r
+ ucm = new UserCertificateModel(new UserModel(params.username));\r
+ }\r
+\r
+ // save latest expiration date\r
+ if (ucm.expires == null || clientMetadata.notAfter.after(ucm.expires)) {\r
+ ucm.expires = clientMetadata.notAfter;\r
+ }\r
+ ucm.update(config);\r
+ config.save();\r
+ \r
+ if (params.sendEmail) {\r
+ if (StringUtils.isEmpty(user.emailAddress)) {\r
+ System.out.print(indent);\r
+ System.out.println(MessageFormat.format("User \"{0}\" does not have an email address.", user.username));\r
+ } else {\r
+ // send email\r
+ MailExecutor mail = new MailExecutor(Params.FILESETTINGS);\r
+ if (mail.isReady()) {\r
+ Message message = mail.createMessage(user.emailAddress);\r
+ message.setSubject("Your Gitblit client certificate for " + clientMetadata.serverHostname);\r
+\r
+ // body of email\r
+ String body = X509Utils.processTemplate(new File(caStore.getParentFile(), "mail.tmpl"), clientMetadata);\r
+ if (StringUtils.isEmpty(body)) {\r
+ body = MessageFormat.format("Hi {0}\n\nHere is your client certificate bundle.\nInside the zip file are installation instructions.", user.getDisplayName());\r
+ }\r
+ Multipart mp = new MimeMultipart();\r
+ MimeBodyPart messagePart = new MimeBodyPart();\r
+ messagePart.setText(body);\r
+ mp.addBodyPart(messagePart);\r
+\r
+ // attach zip\r
+ MimeBodyPart filePart = new MimeBodyPart();\r
+ FileDataSource fds = new FileDataSource(zip);\r
+ filePart.setDataHandler(new DataHandler(fds));\r
+ filePart.setFileName(fds.getName());\r
+ mp.addBodyPart(filePart);\r
+\r
+ message.setContent(mp);\r
+\r
+ mail.sendNow(message);\r
+ System.out.println();\r
+ System.out.println("Mail sent.");\r
+ } else {\r
+ System.out.print(indent);\r
+ System.out.println("Mail server is not properly configured. Can not send email.");\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * JCommander Parameters class for MakeClientCertificate.\r
+ */\r
+ @Parameters(separators = " ")\r
+ private static class Params {\r
+\r
+ private static final FileSettings FILESETTINGS = new FileSettings(Constants.PROPERTIES_FILE);\r
+\r
+ @Parameter(names = { "--username" }, description = "Username for certificate (CN)", required = true)\r
+ public String username;\r
+\r
+ @Parameter(names = { "--password" }, description = "Password to secure user's certificate (<=7 chars unless JCE Unlimited Strength installed)", required = true)\r
+ public String password;\r
+\r
+ @Parameter(names = { "--hint" }, description = "Hint for password", required = true)\r
+ public String hint;\r
+ \r
+ @Parameter(names = "--duration", description = "Number of days from now until the certificate expires")\r
+ public int duration = 0;\r
+\r
+ @Parameter(names = "--storePassword", description = "Password for CA keystore.")\r
+ public String storePassword = FILESETTINGS.getString(Keys.server.storePassword, "");\r
+ \r
+ @Parameter(names = "--server", description = "Hostname or server identity")\r
+ public String serverHostname = Params.FILESETTINGS.getString(Keys.web.siteName, "localhost");\r
+\r
+ @Parameter(names = "--sendEmail", description = "Send an email to the user with their bundle")\r
+ public boolean sendEmail;\r
+ \r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright 2012 gitblit.com.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package com.gitblit.authority;\r
+\r
+import java.util.Date;\r
+\r
+import org.eclipse.jgit.lib.Config;\r
+import org.eclipse.jgit.lib.Config.SectionParser;\r
+\r
+import com.gitblit.utils.StringUtils;\r
+import com.gitblit.utils.TimeUtils;\r
+import com.gitblit.utils.X509Utils.X509Metadata;\r
+\r
+/**\r
+ * Certificate config file parser.\r
+ * \r
+ * @author James Moger\r
+ */\r
+public class NewCertificateConfig {\r
+ public static final SectionParser<NewCertificateConfig> KEY = new SectionParser<NewCertificateConfig>() {\r
+ public NewCertificateConfig parse(final Config cfg) {\r
+ return new NewCertificateConfig(cfg);\r
+ }\r
+ };\r
+\r
+ public final String OU;\r
+ public final String O;\r
+ public final String L;\r
+ public final String ST;\r
+ public final String C;\r
+ \r
+ public final int duration;\r
+ \r
+ private NewCertificateConfig(final Config c) {\r
+ duration = c.getInt("new", null, "duration", 0);\r
+ OU = c.getString("new", null, "organizationalUnit");\r
+ O = c.getString("new", null, "organization");\r
+ L = c.getString("new", null, "locality");\r
+ ST = c.getString("new", null, "stateProvince");\r
+ C = c.getString("new", null, "countryCode"); \r
+ }\r
+ \r
+ public void update(X509Metadata metadata) {\r
+ update(metadata, "OU", OU);\r
+ update(metadata, "O", O);\r
+ update(metadata, "L", L);\r
+ update(metadata, "ST", ST);\r
+ update(metadata, "C", C);\r
+ if (duration > 0) {\r
+ metadata.notAfter = new Date(System.currentTimeMillis() + duration*TimeUtils.ONEDAY);\r
+ }\r
+ }\r
+ \r
+ private void update(X509Metadata metadata, String oid, String value) {\r
+ if (!StringUtils.isEmpty(value)) {\r
+ metadata.oids.put(oid, value);\r
+ }\r
+ }\r
+ }
\ No newline at end of file
--- /dev/null
+/*\r
+ * Copyright 2012 gitblit.com.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package com.gitblit.authority;\r
+\r
+import java.text.ParseException;\r
+import java.text.SimpleDateFormat;\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.List;\r
+\r
+import org.eclipse.jgit.lib.Config;\r
+import org.eclipse.jgit.lib.Config.SectionParser;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import com.gitblit.Constants;\r
+import com.gitblit.models.UserModel;\r
+\r
+/**\r
+ * User certificate config section parser.\r
+ * \r
+ * @author James Moger\r
+ */\r
+public class UserCertificateConfig {\r
+ public static final SectionParser<UserCertificateConfig> KEY = new SectionParser<UserCertificateConfig>() {\r
+ public UserCertificateConfig parse(final Config cfg) { \r
+ return new UserCertificateConfig(cfg);\r
+ }\r
+ };\r
+ \r
+ public final List<UserCertificateModel> list;\r
+\r
+ private UserCertificateConfig(final Config c) {\r
+ SimpleDateFormat df = new SimpleDateFormat(Constants.ISO8601);\r
+ list = new ArrayList<UserCertificateModel>(); \r
+ for (String username : c.getSubsections("user")) {\r
+ UserCertificateModel uc = new UserCertificateModel(new UserModel(username));\r
+ try {\r
+ uc.expires = df.parse(c.getString("user", username, "expires"));\r
+ } catch (ParseException e) {\r
+ LoggerFactory.getLogger(UserCertificateConfig.class).error("Failed to parse date!", e);\r
+ }\r
+ uc.notes = c.getString("user", username, "notes");\r
+ uc.revoked = new ArrayList<String>(Arrays.asList(c.getStringList("user", username, "revoked"))); \r
+ list.add(uc);\r
+ }\r
+ }\r
+ \r
+ public UserCertificateModel getUserCertificateModel(String username) {\r
+ for (UserCertificateModel ucm : list) {\r
+ if (ucm.user.username.equalsIgnoreCase(username)) {\r
+ return ucm;\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/*\r
+ * Copyright 2012 gitblit.com.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package com.gitblit.authority;\r
+\r
+import java.math.BigInteger;\r
+import java.security.cert.X509Certificate;\r
+import java.text.SimpleDateFormat;\r
+import java.util.ArrayList;\r
+import java.util.Date;\r
+import java.util.List;\r
+\r
+import org.eclipse.jgit.lib.Config;\r
+\r
+import com.gitblit.Constants;\r
+import com.gitblit.models.UserModel;\r
+import com.gitblit.utils.ArrayUtils;\r
+import com.gitblit.utils.TimeUtils;\r
+import com.gitblit.utils.X509Utils.RevocationReason;\r
+\r
+public class UserCertificateModel implements Comparable<UserCertificateModel> {\r
+ public UserModel user;\r
+ public Date expires;\r
+ public List<X509Certificate> certs;\r
+ public List<String> revoked;\r
+ public String notes;\r
+\r
+ public UserCertificateModel(UserModel user) {\r
+ this.user = user;\r
+ }\r
+ \r
+ public void update(Config config) {\r
+ if (expires != null) {\r
+ SimpleDateFormat df = new SimpleDateFormat(Constants.ISO8601);\r
+ config.setString("user", user.username, "expires", df.format(expires));\r
+ }\r
+ if (notes != null) {\r
+ config.setString("user", user.username, "notes", notes);\r
+ }\r
+ if (!ArrayUtils.isEmpty(revoked)) {\r
+ config.setStringList("user", user.username, "revoked", revoked);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public int compareTo(UserCertificateModel o) {\r
+ return user.compareTo(o.user);\r
+ }\r
+ \r
+ public void revoke(BigInteger serial, RevocationReason reason) {\r
+ if (revoked == null) {\r
+ revoked = new ArrayList<String>();\r
+ }\r
+ revoked.add(serial.toString() + ":" + reason.ordinal());\r
+ }\r
+ \r
+ public boolean isRevoked(BigInteger serial) {\r
+ return isRevoked(serial.toString());\r
+ }\r
+\r
+ public boolean isRevoked(String serial) {\r
+ if (ArrayUtils.isEmpty(revoked)) {\r
+ return false;\r
+ }\r
+ String sn = serial + ":";\r
+ for (String s : revoked) {\r
+ if (s.startsWith(sn)) {\r
+ return true;\r
+ }\r
+ }\r
+ return false;\r
+ }\r
+ \r
+ public RevocationReason getRevocationReason(BigInteger serial) {\r
+ try {\r
+ String sn = serial + ":";\r
+ for (String s : revoked) {\r
+ if (s.startsWith(sn)) {\r
+ String r = s.substring(sn.length());\r
+ int i = Integer.parseInt(r);\r
+ return RevocationReason.values()[i];\r
+ }\r
+ }\r
+ } catch (Exception e) {\r
+ }\r
+ return RevocationReason.unspecified;\r
+ }\r
+ \r
+ public CertificateStatus getStatus() {\r
+ if (expires == null) {\r
+ return CertificateStatus.unknown;\r
+ } else if (isExpired(expires)) {\r
+ return CertificateStatus.expired;\r
+ } else if (isExpiring(expires)) {\r
+ return CertificateStatus.expiring;\r
+ }\r
+ return CertificateStatus.ok;\r
+ }\r
+\r
+ public boolean hasExpired() {\r
+ return expires != null && isExpiring(expires);\r
+ }\r
+\r
+ public CertificateStatus getStatus(X509Certificate cert) {\r
+ if (isRevoked(cert.getSerialNumber())) {\r
+ return CertificateStatus.revoked;\r
+ } else if (isExpired(cert.getNotAfter())) {\r
+ return CertificateStatus.expired;\r
+ } else if (isExpiring(cert.getNotAfter())) {\r
+ return CertificateStatus.expiring;\r
+ }\r
+ return CertificateStatus.ok;\r
+ }\r
+ \r
+ private boolean isExpiring(Date date) {\r
+ return (date.getTime() - System.currentTimeMillis()) <= TimeUtils.ONEDAY * 30;\r
+ }\r
+ \r
+ private boolean isExpired(Date date) {\r
+ return date.getTime() < System.currentTimeMillis();\r
+ }\r
+ }
\ No newline at end of file
public String cookie;\r
public String displayName;\r
public String emailAddress;\r
+ public String organizationalUnit;\r
+ public String organization;\r
+ public String locality;\r
+ public String stateProvince;\r
+ public String countryCode;\r
public boolean canAdmin;\r
public boolean canFork;\r
public boolean canCreate;\r