Package org.cafesip.jiplet.realms

Source Code of org.cafesip.jiplet.realms.BaseRealm

/*
* Created on Jul 10, 2005
*
* Copyright 2005 CafeSip.org
*
* 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 org.cafesip.jiplet.realms;

import java.io.File;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;

import javax.sip.header.AuthorizationHeader;
import javax.sip.header.WWWAuthenticateHeader;
import javax.sip.message.Message;

import org.cafesip.jiplet.Jiplet;
import org.cafesip.jiplet.JipletException;
import org.cafesip.jiplet.JipletLogger;
import org.cafesip.jiplet.Pair;
import org.cafesip.jiplet.Realm;

/**
* This class is a base class for a realm implementation. An realm
* implementation can either implement the org.cafesip.jiplet.Realm interface or
* extend this class instead. This class implements many of the methods
* specified by the Realm interface making it easier to create realm
* implementation. If you extend this class, make sure that the realm-param
* specified in server.xml contains the following params: <br>
* <ul>
* <li>nonce-private-key</li>
* <li>domain-uri</li>
* </ul>
* The class extending this class must also call super.init() method from its
* init() method in case it overrides the init() method. In addition the class
* must also implement the abstract method getUserInformation().
*
* @author Amit Chatterjee
*/
public abstract class BaseRealm implements Realm
{
    private String realmName;

    private File confDir;

    private String noncePrivateKey = "JIPLET";

    private String domainUri;

    private String opaque;
   
    private boolean defaultRealm;
   
    private HashMap params;

    /**
     * A constructor for this class.
     *
     * 
     */
    public BaseRealm()
    {
        super();
    }

    /*
     * @see org.cafesip.jiplet.Realm#init(java.lang.String, java.io.File,
     *              java.util.HashMap, boolean)
     */
    public void init(String name, File confDir, HashMap params, boolean defaultRealm)
            throws JipletException
    {
        try
        {
            this.params = params;
            this.defaultRealm = defaultRealm;
           
            realmName = name;
            this.confDir = confDir;
            String key = (String) params.get("nonce-private-key");
            if (key != null)
            {
                noncePrivateKey = key;
            }

            String uri = (String) params.get("domain-uri");
            if (uri != null)
            {
                domainUri = uri;
            }

            opaque = computeNonce();
            if (JipletLogger.isDebugEnabled() == true)
            {
                JipletLogger.debug("For the realm " + name + ", the opaque value is " + opaque);
            }
        }
        catch (Exception e)
        {
            throw new JipletException(e);
        }
    }

    private String computeNonce()
    {
        byte[] code = new byte[12];
        long date =  (new Date()).getTime();
        int key =  noncePrivateKey.hashCode();
        int index = 0;
       
        code[index++] = (byte)(date & 0xFF);
        code[index++] = (byte)( (date >> 8) & 0xFF);
        code[index++] = (byte)( (date >> 16) & 0xFF);
        code[index++] = (byte)( (date >> 24) & 0xFF);
        code[index++] = (byte)( (date >> 32) & 0xFF);
        code[index++] = (byte)( (date >> 40) & 0xFF);
        code[index++] = (byte)( (date >> 48) & 0xFF);
        code[index++] = (byte)( (date >> 56) & 0xFF);
       
        code[index++] = (byte)(key & 0xFF);
        code[index++] = (byte)( (key >> 8) & 0xFF)
        code[index++] = (byte)( (key >> 16) & 0xFF);
        code[index++] = (byte)( (key >> 24) & 0xFF);
      
        return Base64.encodeBytes(code);
    }

    /*
     * @see org.cafesip.jiplet.Realm#getRealmName()
     */
    public String getRealmName()
    {
        return realmName;
    }

    /*
     * @see org.cafesip.jiplet.Realm#getAuthenticationHeader(org.cafesip.jiplet.Jiplet,
     *              javax.sip.message.Message message,
     *              java.lang.String, boolean)
     */
    public WWWAuthenticateHeader getAuthenticationHeader(Jiplet jiplet,
            Message message,
            String headerType, boolean stale)
    {
        try
        {
            WWWAuthenticateHeader header = null;

            if (headerType.equals(WWWAuthenticateHeader.NAME) == true)
            {
                header = jiplet.getHeaderFactory().createWWWAuthenticateHeader(
                        "Digest");
            }
            else
            {
                header = jiplet.getHeaderFactory()
                        .createProxyAuthenticateHeader("Digest");
            }
            String nonce = computeNonce();
            header.setNonce(nonce);
            header.setAlgorithm("MD5");
            header.setRealm(realmName);
            header.setDomain(domainUri);
            header.setOpaque(opaque);
            header.setStale(stale);
            return header;
        }
        catch (ParseException e)
        {
            JipletLogger.fatal("Error creating authentication header: "
                    + e.getMessage());
            return null;
        }
    }

    /*
     * @see org.cafesip.jiplet.Realm#authenticate(javax.sip.header.AuthorizationHeader)
     */
    public String[] authenticate(String method, AuthorizationHeader header)
    {
        try
        {
            if (header.getOpaque().equals(getOpaque()) == false)
            {
                if (JipletLogger.isDebugEnabled() == true)
                {
                    JipletLogger
                            .debug("Received a SIP request with invalid OPAQUE value");
                }
                return null;
            }

            String name = header.getUsername();
            Pair p = getUserInformation(name);
            if (p == null)
            {
                if (JipletLogger.isDebugEnabled() == true)
                {
                    JipletLogger
                            .debug("Received an authentication request from an unknown user : "
                                    + name);
                }
                return null;
            }

            // the user is found, verify if the response matches
            String c_response = MessageDigestAlgorithm.calculateResponse(header
                    .getAlgorithm(), name, getRealmName(), (String) p
                    .getFirst(), header.getNonce(), header.getCNonce(), header
                    .getCNonce(), method, header.getURI().toString(), null,
                    header.getQop());
            if (c_response.equals(header.getResponse()) == false)
            {
                if (JipletLogger.isDebugEnabled() == true)
                {
                    JipletLogger.debug("Authentication failure for user "
                            + name);
                }
                return null;
            }

            if (JipletLogger.isDebugEnabled() == true)
            {
                JipletLogger
                        .debug("User " + name + " has been authenticated. ");
            }
            return (String[]) p.getSecond();
        }
        catch (Exception e)
        {
            JipletLogger
                    .fatal("While authenticating an user, receved exception "
                            + e.getClass().getName() + " : " + e.getMessage()
                            + "\n" + JipletLogger.getStackTrace(e));
            return null;
        }
    }

    /**
     * @return Returns the confDir.
     */
    protected File getConfDir()
    {
        return confDir;
    }

    /**
     * @return Returns the opaque.
     */
    protected String getOpaque()
    {
        return opaque;
    }

    /**
     * A class extending this class must implement this interface.
     *
     * @param user
     * @return Returns a Pair object. The first item in the Pair is the password
     *                 and the second item is a String[] containing the roles for the
     *                 user.
     */
    public abstract Pair getUserInformation(String user) throws Exception;
   
    public boolean isDefaultRealm()
    {
        return defaultRealm;
    }
    public HashMap getParams()
    {
        return params;
    }
}
TOP

Related Classes of org.cafesip.jiplet.realms.BaseRealm

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.