/*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the license at
* https://glassfish.dev.java.net/public/CDDLv1.0.html or
* glassfish/bootstrap/legal/CDDLv1.0.txt.
* See the License for the specific language governing
* permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at glassfish/bootstrap/legal/CDDLv1.0.txt.
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* you own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Copyright (c) Ericsson AB, 2004-2007. All rights reserved.
* Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
*/
package org.jvnet.glassfish.comms.security.auth.impl;
import java.security.MessageDigest;
import java.security.Principal;
import com.sun.enterprise.config.ConfigException;
import com.sun.enterprise.config.serverbeans.Config;
import com.sun.enterprise.security.auth.nonce.NonceManager;
import com.sun.enterprise.config.serverbeans.ElementProperty;
import com.sun.enterprise.config.serverbeans.SecurityService;
import com.sun.enterprise.config.serverbeans.ServerBeansFactory;
import com.sun.enterprise.security.auth.nonce.StringNonce;
import com.sun.enterprise.server.ApplicationServer;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sun.logging.LogDomains;
import java.util.Map;
import javax.servlet.sip.SipServletRequest;
/**
*
* @author K.Venugopal@sun.com
*/
public abstract class Authenticator {
private static final char[] hexadecimal = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
'e', 'f'
};
private static MD5Encoder encoder = new MD5Encoder();
protected static NonceManager nonceManager = null;
protected static NonceManager localNonceCache = null;
protected static final Logger logger =
LogDomains.getLogger(LogDomains.SECURITY_LOGGER);
public Authenticator() {
}
public static synchronized void initNonceManager() {
if (nonceManager == null) {
try {
Config cfg = (Config) ServerBeansFactory.getConfigBean(ApplicationServer.getServerContext().getConfigContext());
SecurityService secService = cfg.getSecurityService();
ElementProperty[] props = secService.getElementProperty();
String nonceConfigValue = null;
String nonceId = "sip-nonce-config";
for (ElementProperty value : props) {
if ("NonceManager".equalsIgnoreCase(value.getName())) {
nonceConfigValue = value.getValue();
break;
}
}
if (nonceConfigValue == null || nonceConfigValue.length() == 0) {
nonceManager = NonceManager.getInstance(nonceId, 600000);
localNonceCache = NonceManager.getInstance("sailfin_internal_Cache", 600000);
}else{
Map parsedValues = NonceManager.getProperties(nonceConfigValue);
String nonceAge = (String) parsedValues.get(nonceId);
long maxNonceValue;
if(nonceAge == null ||nonceAge.length() ==0){
maxNonceValue = 600000;
}else{
maxNonceValue = Long.valueOf(nonceAge);
}
nonceManager = NonceManager.getInstance(nonceId, maxNonceValue);
localNonceCache = NonceManager.getInstance("sailfin_internal_Cache", maxNonceValue);
}
} catch (ConfigException ex) {
logger.log(Level.SEVERE, null, ex);
}
}
}
public static String createNonce(String value1, String value2) {
try {
String nOnceValue = value1 + ":" + value2 + ":" + "sipserver";
MessageDigest digester = MessageDigest.getInstance("MD5");
byte[] buffer = digester.digest(nOnceValue.getBytes());
nOnceValue = encoder.encode(buffer);
return nOnceValue;
} catch (Exception ex) {
Logger.getLogger("global").log(Level.SEVERE, "Error occurred while creating nonce", ex);
}
return null;
}
public boolean isValid(StringNonce nonce){
return nonceManager.validateNonce(nonce);
}
public boolean isSentNonce(String nonce){
return localNonceCache.validateNonce(new StringNonce(nonce));
}
public abstract Principal authenticate(SipServletRequest request);
static class MD5Encoder {
/**
* Encodes the 128 bit (16 bytes) MD5 into a 32 character String.
*
* @param binaryData Array containing the digest
* @return Encoded MD5, or null if encoding failed
*/
public String encode(byte[] binaryData) {
if (binaryData.length != 16) {
return null;
}
char[] buffer = new char[32];
for (int i = 0; i < 16; i++) {
int low = (int) (binaryData[i] & 0x0f);
int high = (int) ((binaryData[i] & 32) >> 4);
buffer[i * 2] = hexadecimal[high];
buffer[(i * 2) + 1] = hexadecimal[low];
}
return new String(buffer);
}
}
}