All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.jradius.webservice.WebServiceProcessor Maven / Gradle / Ivy

/**
 * JRadius - A Radius Server Java Adapter
 * Copyright (C) 2004-2006 PicoPoint, B.V.
 * Copyright (c) 2006-2007 David Bird 
 * 
 * This program 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 program 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 program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */

package net.jradius.webservice;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;

import net.jradius.exception.RadiusException;
import net.jradius.handler.chain.JRCommand;
import net.jradius.log.RadiusLog;
import net.jradius.server.ListenerRequest;
import net.jradius.server.Processor;
import net.jradius.server.TCPListenerRequest;

/**
 * JRadius Relay Request Processor
 * 
 * @author David Bird
 */
public class WebServiceProcessor extends Processor
{
	protected static final byte[] newline = toHTTPBytes("\r\n");
	protected static final byte[] ctype = toHTTPBytes("Content-Type: text/xml\r\n");
	protected static final byte[] clength = toHTTPBytes("Content-Length: ");
	protected static final byte[] server = toHTTPBytes("Server: JRadius\r\n");  
	protected static final byte[] conclose = toHTTPBytes("Connection: close\r\n");
	protected static final byte[] ok = toHTTPBytes(" 200 OK\r\n");
	protected static final byte[] found = toHTTPBytes(" 302 Found\r\n");
	protected static final byte[] unauthorized = toHTTPBytes(" 401 Unauthorized\r\n");
	private boolean wantClientCertificates = true;
    
	protected void processRequest(ListenerRequest listenerRequest) throws Exception
	{
		TCPListenerRequest tcpListenerRequest = (TCPListenerRequest)listenerRequest;
		Socket socket = tcpListenerRequest.getSocket();
		socket.setSoTimeout(15000); // 15 second read timeout
        
		X509Certificate x509 = null;
        
        if (socket instanceof SSLSocket && wantClientCertificates)
        {
        	SSLSocket sslSocket = (SSLSocket) socket;
        	sslSocket.setWantClientAuth(true);
        	try
        	{
            	SSLSession sslSession = sslSocket.getSession();
	        	Certificate[] certs = sslSession.getPeerCertificates();
				if (certs != null)
				{
					Certificate cert = certs[0];
					if (cert instanceof X509Certificate)
						x509 = (X509Certificate) cert;
				}
			} 
			catch (Throwable e) 
			{
			}
        }
        
        WebServiceRequest request = null;
        OutputStream os = null; 

        try
        {
            request = (WebServiceRequest) listenerRequest.getRequestEvent();
            request.setServerVariableMap(listenerRequest.getServerVariables());
            request.setCertificate(x509);
            request.setApplicationContext(getApplicationContext());
            processRequest(request);

            os = socket.getOutputStream();
            sendResponse(request, os);
        } 
        finally
        {
            if (os != null)
            {
            	try { os.flush(); } catch (Exception e) { }
            }

            if (!tcpListenerRequest.isKeepAlive())
            {
	            if (os != null)
	            {
	            	try { os.close(); } catch (Exception e) { }
	            }
	            socket.close();
            }
        }
    }
 
    protected void runHandlers(WebServiceRequest request)
    {
        RadiusLog.debug("Processing WebServiceRequest: " + request.toString());
        List handlers = getRequestHandlers();
        if (handlers == null) return;

        for (JRCommand handler : handlers)
        {
            boolean stop = false;
            try
            {
                if (handler.doesHandle(request))
                {
                    stop = handler.execute(request);
                    if (stop) break;
                }
            }
            catch (WebServiceException e)
            {
                RadiusLog.error(e.getMessage(), e);
                break;
            }
            catch (RadiusException e)
            {
                RadiusLog.error(e.getMessage(), e);
                break;
            }
            catch (Throwable e)
            {
                RadiusLog.error(e.getMessage(), e);
                break;
            }
        }
    }
    
    protected void processRequest(WebServiceRequest request)
    {
    	runHandlers(request);
    }

    private void sendResponse(WebServiceRequest request, OutputStream out) throws IOException
    {
        WebServiceResponse response = request.getResponse();
        
        if (response == null)
        {
            RadiusLog.error("No response found for WebServiceRequest: " + request.toString());
            writeBadRequest(out, request.getHttpVersion());
            return;
        }

        writeResponse(out, request.getHttpVersion(), response.getHeaders(), 
        		response.getContent(), response.getSendFile());
    }
    
    private void writeResponse(OutputStream writer, String httpVersion, Map headers,
    		byte[] payload, File sendFile) throws IOException
    {
        boolean wroteCT = false;
        boolean wroteCL = false;
        
        writer.write(toHTTPBytes(httpVersion));

        if (headers.get("Location") != null)
            writer.write(found);
        else if (headers.get("WWW-Authenticate") != null)
        	writer.write(unauthorized);
        else
            writer.write(ok);
        
        writer.write(server);
        writer.write(conclose);
        for (Iterator i = headers.entrySet().iterator(); i.hasNext();)
        {
            Map.Entry entry = (Map.Entry)i.next();
            String key = (String)entry.getKey();
            writer.write(toHTTPBytes(key));
            writer.write(toHTTPBytes(": "));
            writer.write(toHTTPBytes((String)entry.getValue()));
            writer.write(newline);
            if (key.equalsIgnoreCase("content-type")) wroteCT = true;
            else if (key.equalsIgnoreCase("content-length")) wroteCL = true;
        }
        if (!wroteCT) writer.write(ctype);
        if (!wroteCL)
        {
        	long totalLength = payload == null ? 0 : payload.length;
        	totalLength += sendFile == null ? 0 : sendFile.length();
            writer.write(clength);
            writer.write(toHTTPBytes(Long.toString(totalLength)));
            writer.write(newline);
        }
        writer.write(newline);
        if (payload != null)
        	writer.write(payload);
        if (sendFile != null)
        {
        	int len;
        	byte[] data = new byte[512];
        	InputStream in = new FileInputStream(sendFile);
        	do {
        		len = in.read(data);
        		if (len > 0)
        			writer.write(data, 0, len);
        	} while (len > 0);
        	in.close();
        }
    }

    private void writeBadRequest(OutputStream writer, String httpVersion) throws IOException
    {
        writer.write(toHTTPBytes(httpVersion));
        writer.write(toHTTPBytes(" 400 Bad Request"));
        writer.write(newline);
        writer.write(server);
        writer.write(newline);
        writer.write(toHTTPBytes("Invalid request"));
    }
    
    protected static byte[] toHTTPBytes(String text)
    {
    	if (text == null) text = "";
    	
        try
        {
            return text.getBytes("US-ASCII");
        }
        catch (UnsupportedEncodingException e)
        {
            throw new Error(e.getMessage());
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy