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