Package local.server

Source Code of local.server.AuthenticationServerImpl

/*
* Copyright (C) 2005 Luca Veltri - University of Parma - Italy
*
* This source code is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This source code 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this source code; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* Author(s):
* Luca Veltri (luca.veltri@unipr.it)
*/

package local.server;


import org.zoolu.sip.address.*;
import org.zoolu.sip.header.WwwAuthenticateHeader;
import org.zoolu.sip.header.AuthorizationHeader;
import org.zoolu.sip.header.AuthenticationInfoHeader;
import org.zoolu.sip.header.ProxyAuthenticateHeader;
import org.zoolu.sip.header.ProxyAuthorizationHeader;
import org.zoolu.sip.message.*;
import org.zoolu.sip.provider.SipStack;
import org.zoolu.sip.authentication.DigestAuthentication;
import org.zoolu.tools.Log;
import org.zoolu.tools.LogLevel;
import org.zoolu.tools.Parser;
import org.zoolu.tools.MD5;


/** Class AuthenticationServerImpl implements an AuthenticationServer
  * for HTTP Digest authentication.
  */
public class AuthenticationServerImpl implements AuthenticationServer
{  

   /** Server authentication. */
   protected static final int SERVER_AUTHENTICATION=0;

   /** Proxy authentication. */
   protected static final int PROXY_AUTHENTICATION=1;


   /** Event logger. */
   protected Log log=null;

   /** The repository of users's authentication data. */
   protected AuthenticationService authentication_service;
  
   /** The authentication realm. */
   protected String realm;
  
   /** The authentication scheme. */
   protected String authentication_scheme="Digest";

   /** The authentication qop-options. */
   protected String qop_options="auth,auth-int";

   /** The current random value. */
   protected byte[] rand;

   /** DIGEST */
   //public static final String DIGEST="Digest";
   /** AKA */
   //public static final String AKA="AKA";
   /** CHAP */
   //public static final String CHAP="CHAP";


   /** Costructs a new AuthenticationServerImpl. */
   public AuthenticationServerImpl(String realm, AuthenticationService authentication_service, Log log)
   {  init(realm,authentication_service,log);
   }
  
   /** Inits the AuthenticationServerImpl. */
   private void init(String realm, AuthenticationService authentication_service, Log log)
   {  this.log=log;
      this.realm=realm;
      this.authentication_service=authentication_service;
      this.rand=pickRandBytes();
   }

   /** Gets the realm. */
   /*public String getRealm()
   {  return realm;
   }*/


   /** Gets the qop-options. */
   /*public String getQopOptions()
   {  return qop_options;
   }*/


   /** Gets the current rand value. */
   /*public String getRand()
   {  return HEX(rand);
   }*/


   /** Authenticates a SIP request.
     * @param msg is the SIP request to be authenticated
     * @return it returns the error Message in case of authentication failure,
     * or null in case of authentication success. */
   public Message authenticateRequest(Message msg)
   {  return authenticateRequest(msg,SERVER_AUTHENTICATION);
   }


   /** Authenticates a SIP request.
     * @param msg is the SIP request to be authenticated
     * @return it returns the error Message in case of authentication failure,
     * or null in case of authentication success. */
   public Message authenticateProxyRequest(Message msg)
   {  return authenticateRequest(msg,PROXY_AUTHENTICATION);
   }


   /** Authenticates a SIP request.
     * @param msg is the SIP request to be authenticated
     * @param proxy_authentication whether performing Proxy-Authentication or simple Authentication
     * @return it returns the error Message in case of authentication failure,
     * or null in case of authentication success. */
   protected Message authenticateRequest(Message msg, int type)
   {  Message err_resp=null;

      //String username=msg.getFromHeader().getNameAddress().getAddress().getUserName();
      //String user=username+"@"+realm;

      AuthorizationHeader ah;
      if (type==SERVER_AUTHENTICATION) ah=msg.getAuthorizationHeader();
      else ah=msg.getProxyAuthorizationHeader();
        
      if (ah!=null && ah.getNonceParam().equals(HEX(rand)))
      {
         //String username=ah.getUsernameParam();
         String realm=ah.getRealmParam();
         String nonce=ah.getNonceParam();
         String username=ah.getUsernameParam();
         String scheme=ah.getAuthScheme();
        
         String user=username+"@"+realm;
        
         if (authentication_service.hasUser(user))
         { 
            if (authentication_scheme.equalsIgnoreCase(scheme))
            { 
               DigestAuthentication auth=new DigestAuthentication(msg.getRequestLine().getMethod(),ah,null,keyToPasswd(authentication_service.getUserKey(user)));

               // check user's authentication response
               boolean is_authorized=auth.checkResponse();

               rand=pickRandBytes();       
                 
               if (!is_authorized)
               {  // authentication/authorization failed
                  int result=403; // response code 403 ("Forbidden")
                  err_resp=MessageFactory.createResponse(msg,result,SipResponses.reasonOf(result),null);
                  printLog("LOGIN ERROR: Authentication of '"+user+"' failed",LogLevel.HIGH);
               }
               else
               // authentication/authorization successed
                  printLog("Authentication of '"+user+"' successed",LogLevel.HIGH);
               }
            }
            else
            // authentication/authorization failed
               int result=400; // response code 400 ("Bad request")
               err_resp=MessageFactory.createResponse(msg,result,SipResponses.reasonOf(result),null);
               printLog("Authentication method '"+scheme+"' not supported.",LogLevel.HIGH);
            }
         }
         else
         // no authentication credential found for this user
            int result=404; // response code 404 ("Not Found")
            err_resp=MessageFactory.createResponse(msg,result,SipResponses.reasonOf(result),null)
         }
      }
      else
      // no Authorization header found
         int result;
         if (type==SERVER_AUTHENTICATION) result=401; // response code 401 ("Unauthorized")
         else result=407; // response code 407 ("Proxy Authentication Required")
         err_resp=MessageFactory.createResponse(msg,result,SipResponses.reasonOf(result),null);
         WwwAuthenticateHeader wah;
         if (type==SERVER_AUTHENTICATION) wah=new WwwAuthenticateHeader("Digest");
         else wah=new ProxyAuthenticateHeader("Digest");
         wah.addRealmParam(realm);
         wah.addQopOptionsParam(qop_options);
         wah.addNonceParam(HEX(rand));
         err_resp.setWwwAuthenticateHeader(wah);
      }
      return err_resp;
   }


   /** Gets AuthenticationInfoHeader. */
   public AuthenticationInfoHeader getAuthenticationInfoHeader()
   {  AuthenticationInfoHeader aih=new AuthenticationInfoHeader();
      aih.addRealmParam(realm);
      aih.addQopOptionsParam(qop_options);
      aih.addNextnonceParam(HEX(rand));
      return aih;
   }


   /** Picks a random array of 16 bytes. */
   private static byte[] pickRandBytes()
   {  return MD5(Long.toHexString(org.zoolu.tools.Random.nextLong()));
   }

   /** Converts the byte[] key in a String passwd. */
   private static String keyToPasswd(byte[] key)
   {  return new String(key);
   }

   /** Calculates the MD5 of a String. */
   private static byte[] MD5(String str)
   {  return MD5.digest(str);
   }

   /** Calculates the MD5 of an array of bytes. */
   private static byte[] MD5(byte[] bb)
   {  return MD5.digest(bb);
   }

   /** Calculates the HEX of an array of bytes. */
   private static String HEX(byte[] bb)
   {  return MD5.asHex(bb);
   }

   // ****************************** Logs *****************************

   /** Adds a new string to the default Log */
   protected void printLog(String str, int level)
   {  if (log!=null) log.println("AuthenticationServer: "+str,level+SipStack.LOG_LEVEL_UA)
   }

}
TOP

Related Classes of local.server.AuthenticationServerImpl

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.