001/*
002 *  (C) Copyright 2000-2003 Yale University. All rights reserved.
003 *
004 *  THIS SOFTWARE IS PROVIDED "AS IS," AND ANY EXPRESS OR IMPLIED
005 *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
006 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE EXPRESSLY
007 *  DISCLAIMED. IN NO EVENT SHALL YALE UNIVERSITY OR ITS EMPLOYEES BE
008 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
009 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED, THE COSTS OF
010 *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA OR
011 *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
012 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
013 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
014 *  SOFTWARE, EVEN IF ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH
015 *  DAMAGE.
016 *
017 *  Redistribution and use of this software in source or binary forms,
018 *  with or without modification, are permitted, provided that the
019 *  following conditions are met:
020 *
021 *  1. Any redistribution must include the above copyright notice and
022 *  disclaimer and this list of conditions in any related documentation
023 *  and, if feasible, in the redistributed software.
024 *
025 *  2. Any redistribution must include the acknowledgment, "This product
026 *  includes software developed by Yale University," in any related
027 *  documentation and, if feasible, in the redistributed software.
028 *
029 *  3. The names "Yale" and "Yale University" must not be used to endorse
030 *  or promote products derived from this software.
031 */
032
033package edu.yale.its.tp.cas.proxy;
034
035import java.io.*;
036import java.util.*;
037import javax.servlet.*;
038import javax.servlet.http.*;
039import edu.yale.its.tp.cas.util.SecureURL;
040
041/**
042 * Receives and keeps track fo PGTs and serial PGT identifiers (IOUs) sent by CAS in response to a ServiceValidate
043 * request.
044 */
045public class ProxyTicketReceptor extends HttpServlet {
046
047    // *********************************************************************
048    // Constants
049
050    private static final String PGT_IOU_PARAM = "pgtIou";
051
052    private static final String PGT_ID_PARAM = "pgtId";
053
054    // *********************************************************************
055    // Private state
056
057    private static Map pgt;
058
059    private static String casProxyUrl;
060
061    // *********************************************************************
062    // Initialization
063
064    public void init(ServletConfig config) throws ServletException {
065        super.init(config);
066        synchronized (ProxyTicketReceptor.class) {
067            if (pgt == null)
068                pgt = new HashMap();
069
070            // retrieve the URL for CAS
071            if (casProxyUrl == null) {
072                ServletContext app = config.getServletContext();
073                casProxyUrl = (String) app.getInitParameter("edu.yale.its.tp.cas.proxyUrl");
074                if (casProxyUrl == null)
075                    throw new ServletException("need edu.yale.its.tp.cas.proxyUrl");
076            }
077        }
078    }
079
080    // *********************************************************************
081    // Request handling
082
083    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
084        doGet(request, response);
085    }
086
087    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
088        String pgtId = request.getParameter(PGT_ID_PARAM);
089        String pgtIou = request.getParameter(PGT_IOU_PARAM);
090        if (pgtId != null && pgtIou != null) {
091            synchronized (pgt) {
092                pgt.put(pgtIou, pgtId);
093            }
094        }
095        PrintWriter out = response.getWriter();
096        out.println("<casClient:proxySuccess " + "xmlns:casClient=\"http://www.yale.edu/tp/casClient\"/>");
097        out.flush();
098    }
099
100    // *********************************************************************
101    // Interface to package members
102
103    // NOTE: PUBLIC FOR THE MOMENT
104
105    /**
106     * Retrieves a proxy ticket using the PGT that corresponds to the given PGT IOU.
107     */
108    public static String getProxyTicket(String pgtIou, String target) throws IOException {
109        synchronized (ProxyTicketReceptor.class) {
110            // ensure state is sensible
111            if (casProxyUrl == null || pgt == null)
112                throw new IllegalStateException("getProxyTicket() only works after servlet has been initialized");
113        }
114
115        // retrieve PGT
116        String pgtId = null;
117        synchronized (pgt) {
118            pgtId = (String) pgt.get(pgtIou);
119        }
120        if (pgtId == null)
121            return null;
122
123        // retrieve an XML response from CAS's "Proxy" actuator
124        String url = casProxyUrl + "?pgt=" + pgtId + "&targetService=" + target;
125        String response = SecureURL.retrieve(url);
126
127        // parse this response (use a lightweight approach for now)
128        if (response.indexOf("<cas:proxySuccess>") != -1 && response.indexOf("<cas:proxyTicket>") != -1) {
129            int startIndex = response.indexOf("<cas:proxyTicket>") + "<cas:proxyTicket>".length();
130            int endIndex = response.indexOf("</cas:proxyTicket>");
131            return response.substring(startIndex, endIndex);
132        } else {
133            // generic failure
134            return null;
135        }
136    }
137}