Java tutorial
/* * Copyright (c) 2011, Martijn Brinkers, Djigzo. * * This file is part of Djigzo email encryption. * * Djigzo is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License * version 3, 19 November 2007 as published by the Free Software * Foundation. * * Djigzo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public * License along with Djigzo. If not, see <http://www.gnu.org/licenses/> * * Additional permission under GNU AGPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or * combining it with aspectjrt.jar, aspectjweaver.jar, tyrex-1.0.3.jar, * freemarker.jar, dom4j.jar, mx4j-jmx.jar, mx4j-tools.jar, * spice-classman-1.0.jar, spice-loggerstore-0.5.jar, spice-salt-0.8.jar, * spice-xmlpolicy-1.0.jar, saaj-api-1.3.jar, saaj-impl-1.3.jar, * wsdl4j-1.6.1.jar (or modified versions of these libraries), * containing parts covered by the terms of Eclipse Public License, * tyrex license, freemarker license, dom4j license, mx4j license, * Spice Software License, Common Development and Distribution License * (CDDL), Common Public License (CPL) the licensors of this Program grant * you additional permission to convey the resulting work. */ package mitm.application.djigzo.james.mailets; import java.io.UnsupportedEncodingException; import javax.mail.MessagingException; import mitm.application.djigzo.User; import mitm.application.djigzo.james.ClientSecrets; import mitm.application.djigzo.james.DjigzoMailAttributesImpl; import mitm.application.djigzo.james.EncryptedContainer; import mitm.application.djigzo.service.SystemServices; import mitm.common.properties.HierarchicalPropertiesException; import mitm.common.security.otp.OTPException; import mitm.common.security.otp.OTPGenerator; import org.apache.commons.lang.CharEncoding; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Mailet that generates OTP passwords for all recipients. * * Supported mailet parameters: * * defaultSecret : The default client secret used for generating an OTP (defaults to: changeit) * baseTime : Date (format yyyy-MM-dd) that will be subtracted from the current time (default: 0) * uniqueID : If multiple servers are used this is used to make sure the password ID is unique * defaultPasswordLength : The default length of the generated passwords (in bytes, default: 8 bytes) * catchRuntimeExceptions : If true all RunTimeExceptions are caught * catchErrors : If true all Errors are caught * * @author Martijn Brinkers * */ public class OTPPasswordGenerator extends AbstractGeneratePassword { private final static Logger logger = LoggerFactory.getLogger(OTPPasswordGenerator.class); /* * Generator used for generating the passwords. */ private OTPGenerator otpGenerator; /* * The default client secret used for generating an OTP */ private String defaultSecret; /* * The encoding used for the conversion of passwords to bytes */ private String encoding; @Override protected Logger getLogger() { return logger; } /* * The extra mailet initialization parameters used by this mailet (AbstractGeneratePassword defines * the other parameters) */ private enum Parameter { ENCODING("encoding"), DEFAULT_SECRET("defaultSecret"); private String name; private Parameter(String name) { this.name = name; } }; @Override public void initMailet() throws MessagingException { super.initMailet(); encoding = getInitParameter(Parameter.ENCODING.name); if (StringUtils.isEmpty(encoding)) { encoding = CharEncoding.US_ASCII; } defaultSecret = getInitParameter(Parameter.DEFAULT_SECRET.name); otpGenerator = SystemServices.getOTPGenerator(); } @Override protected String generatePassword(User user, int passwordLength, String passwordID) throws MessagingException { try { ActivationContext activationContext = getActivationContext().get(ACTIVATION_CONTEXT_KEY, ActivationContext.class); /* * Check if a collection of client secrets is stored in the context */ ClientSecrets clientSecrets = (ClientSecrets) activationContext.getTag(); if (clientSecrets == null) { /* * Check if the Mail object contains a collection of Client secrets and if so use it */ clientSecrets = new DjigzoMailAttributesImpl(activationContext.getMail()).getClientSecrets(); if (clientSecrets != null) { /* * The Mail object contains a collection of client secrets. Store it in the context * so we can reuse it for the next user */ activationContext.setTag(clientSecrets); } } String clientSecret = null; if (clientSecrets != null) { EncryptedContainer<String> encryptedSecret = clientSecrets.get(user.getEmail()); if (encryptedSecret != null) { clientSecret = encryptedSecret.get(); } } /* * If the client secret for the user was not found in the Mail attributes, * check if it the user properties contain a client secret */ if (StringUtils.isEmpty(clientSecret)) { clientSecret = user.getUserPreferences().getProperties().getClientSecret(); } /* * If the user properties do not contain a client secret for the user use the default secret */ if (StringUtils.isEmpty(clientSecret)) { clientSecret = defaultSecret; } if (clientSecret == null) { throw new MessagingException("No client secret found for user " + user.getEmail()); } return otpGenerator.generate(clientSecret.getBytes(encoding), passwordID.getBytes(encoding), passwordLength); } catch (HierarchicalPropertiesException e) { throw new MessagingException("Error generating OTP password", e); } catch (UnsupportedEncodingException e) { throw new MessagingException("Error generating password. Unsupported encoding", e); } catch (OTPException e) { throw new MessagingException("Error generating OTP password", e); } } }