Package org.cafesip.jiplet.sip

Source Code of org.cafesip.jiplet.sip.RequestValidation

/*
* RequestValidation.java
*
* Created on April 10, 2003, 6:31 PM
*/

package org.cafesip.jiplet.sip;

import java.util.ListIterator;

import javax.sip.ServerTransaction;
import javax.sip.SipProvider;
import javax.sip.address.URI;
import javax.sip.header.EventHeader;
import javax.sip.header.FromHeader;
import javax.sip.header.HeaderFactory;
import javax.sip.header.MaxForwardsHeader;
import javax.sip.header.ProxyRequireHeader;
import javax.sip.header.UnsupportedHeader;
import javax.sip.header.ViaHeader;
import javax.sip.message.MessageFactory;
import javax.sip.message.Request;
import javax.sip.message.Response;

import org.cafesip.jiplet.Jiplet;

/**
* RFC 3261 16.3 Request Validation: Before an element can proxy a request, it
* MUST verify the message's validity. A valid message must pass the following
* checks: 1. Reasonable Syntax: Here, it is done by the stack, so this step is
* passed!
*
* 2. URI scheme: we just support the "sip", "sips", "tel" schemes, for
* simplicity!!!
*
* 3. Max-Forwards
*
* 4. (Optional) Loop Detection
*
* 5. Proxy-Require: We don't support any option tags!
*
* 6. Proxy-Authorization
*
* @author deruelle
*/
public class RequestValidation
{
    private Jiplet proxy;

    private boolean presenceServer;
   
    /** Creates a new instance of RequestValidation */
    protected RequestValidation(Jiplet proxy, boolean presenceServer)
    {
        this.proxy = proxy;
        this.presenceServer = presenceServer;
    }

    protected boolean validateRequest(SipProvider sipProvider, Request request,
            ServerTransaction serverTransaction)
    {
        try
        {
            MessageFactory messageFactory = proxy.getMessageFactory();

            // Important check: the server transaction can be null! So, in this
            // case,
            // we have to reply an eventual error code statelessly

            if (!checkURIScheme(request))
            {
                // Let's return a 416 Unsupported URI scheme
                Response response = messageFactory.createResponse(
                        Response.UNSUPPORTED_URI_SCHEME, request);
                if (serverTransaction != null)
                    serverTransaction.sendResponse(response);
                else
                    sipProvider.sendResponse(response);
                return false;
            }

            if (!checkMaxForwards(request))
            {
                // Let's return a 483 too many hops
                Response response = messageFactory.createResponse(
                        Response.TOO_MANY_HOPS, request);
                if (serverTransaction != null)
                    serverTransaction.sendResponse(response);
                else
                    sipProvider.sendResponse(response);
                return false;
            }

            if (!checkLoopDetection(request))
            {
                // Let's return a 482 Loop detection
                Response response = messageFactory.createResponse(
                        Response.LOOP_DETECTED, request);
                if (serverTransaction != null)
                    serverTransaction.sendResponse(response);
                else
                    sipProvider.sendResponse(response);
                return false;
            }

            if (!checkProxyRequire(request))
            {
                // Let's return a 420 Bad Extension
                Response response = messageFactory.createResponse(
                        Response.BAD_EXTENSION, request);

                // We have to add a Unsupported header listing the Option tags
                // that we don't support:
                HeaderFactory headerFactory = proxy.getHeaderFactory();
                ProxyRequireHeader prh = (ProxyRequireHeader) request
                        .getHeader(ProxyRequireHeader.NAME);
                if (prh != null)
                {
                    UnsupportedHeader unsupportedHeader = headerFactory
                            .createUnsupportedHeader(prh.getOptionTag());
                    response.setHeader(unsupportedHeader);
                }

                if (serverTransaction != null)
                    serverTransaction.sendResponse(response);
                else
                    sipProvider.sendResponse(response);

                return false;
            }

            // Let's add some more important basics checks:
            // - From tag presence.

            if (!checkFromTag(request))
            {
                // Let's return a 400 BAD_REQUEST
                Response response = messageFactory.createResponse(
                        Response.BAD_REQUEST, request);
                if (serverTransaction != null)
                    serverTransaction.sendResponse(response);
                else
                    sipProvider.sendResponse(response);
                return false;
            }

            // For Event notifications:
            if (presenceServer)
            {
                String method = request.getMethod();
                if (method.equals("SUBSCRIBE"))
                {

                    // RFC 3265 3.1.1:
                    /*
                     * Subscribers MUST include exactly one "Event" header in
                     * SUBSCRIBE requests, indicating to which event or class of
                     * events they are subscribing.
                     */
                    if (!checkEventHeader(request))
                    {
                        // Let's return a 400 BAD_REQUEST
                        Response response = messageFactory.createResponse(
                                Response.BAD_REQUEST, request);
                        if (serverTransaction != null)
                            serverTransaction.sendResponse(response);
                        else
                            sipProvider.sendResponse(response);
                        return false;
                    }
                }
            }

            // All the checks are passed:
            return true;

        }
        catch (Exception e)
        {
            return false;
        }
    }

    private boolean checkURIScheme(Request request)
    {
        try
        {
            URI requestURI = request.getRequestURI();
            String uriScheme = requestURI.getScheme();
            return uriScheme.equals("sip") || uriScheme.equals("sips")
                    || uriScheme.equals("tel");
        }
        catch (Exception e)
        {
            return false;
        }
    }

    private boolean checkMaxForwards(Request request)
    {
        try
        {
            MaxForwardsHeader mf = (MaxForwardsHeader) request
                    .getHeader(MaxForwardsHeader.NAME);
            if (mf == null)
            {
                // We don't add one here!!! We will do it on the cloned request
                // that we are going to forward later.
                return true;
            }

            if (mf.getMaxForwards() == 0)
            {
                return false;
            }
            else
            {
                // We don't decrement here!!! We will do it on the cloned
                // request
                // that we are going to forward later.
                return true;
            }
        }
        catch (Exception e)
        {
            return false;
        }
    }

    private boolean checkLoopDetection(Request request)
    {
        try
        {
            ListIterator viaList = request.getHeaders(ViaHeader.NAME);
            if (viaList == null)
                return false;

            while (viaList.hasNext())
            {
                ViaHeader viaHeader = (ViaHeader) viaList.next();
                if (proxy.hasAddress(viaHeader.getHost(), viaHeader.getPort()) == true)
                {
                    // We have to check the branch-ids...
                    // TODO.

                    return false;
                }
            }
            return true;
        }
        catch (Exception e)
        {
            return false;
        }
    }

    private boolean checkProxyRequire(Request request)
    {
        try
        {

            ProxyRequireHeader prh = (ProxyRequireHeader) request
                    .getHeader(ProxyRequireHeader.NAME);
            if (prh == null)
                return true;
            else
            {
                // We don't support any option tags. So we reject the request:
                return false;
            }
        }
        catch (Exception e)
        {
            return false;
        }
    }

    private boolean checkFromTag(Request request)
    {
        try
        {
            if (request.getMethod().equals(Request.REGISTER))
                return true;
            FromHeader fh = (FromHeader) request.getHeader(FromHeader.NAME);
            return (fh.getTag() != null);

        }
        catch (Exception e)
        {
            return false;
        }
    }

    private boolean checkEventHeader(Request request)
    {
        try
        {
            EventHeader eventHeader = (EventHeader) request
                    .getHeader(EventHeader.NAME);
            // return eventHeader!=null;
            // For Microsoft interoperability:
            return true;
        }
        catch (Exception e)
        {
            return false;
        }
    }
}
TOP

Related Classes of org.cafesip.jiplet.sip.RequestValidation

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.