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 long serialVersionUID = 1L;
051
052    private static final String PGT_IOU_PARAM = "pgtIou";
053
054    private static final String PGT_ID_PARAM = "pgtId";
055
056    // *********************************************************************
057    // Private state
058
059    private static Map<String, String> pgt;
060
061    private static String casProxyUrl;
062
063    // *********************************************************************
064    // Initialization
065
066    @Override
067    public void init(ServletConfig config) throws ServletException {
068        super.init(config);
069        synchronized (ProxyTicketReceptor.class) {
070            if (pgt == null)
071                pgt = new HashMap<>();
072
073            // retrieve the URL for CAS
074            if (casProxyUrl == null) {
075                ServletContext app = config.getServletContext();
076                casProxyUrl = app.getInitParameter("edu.yale.its.tp.cas.proxyUrl");
077                if (casProxyUrl == null)
078                    throw new ServletException("need edu.yale.its.tp.cas.proxyUrl");
079            }
080        }
081    }
082
083    // *********************************************************************
084    // Request handling
085
086    @Override
087    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
088        doGet(request, response);
089    }
090
091    @Override
092    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
093        String pgtId = request.getParameter(PGT_ID_PARAM);
094        String pgtIou = request.getParameter(PGT_IOU_PARAM);
095        if (pgtId != null && pgtIou != null) {
096            synchronized (pgt) {
097                pgt.put(pgtIou, pgtId);
098            }
099        }
100        @SuppressWarnings("resource")
101        PrintWriter out = response.getWriter();
102        out.println("<casClient:proxySuccess " + "xmlns:casClient=\"http://www.yale.edu/tp/casClient\"/>");
103        out.flush();
104    }
105
106    // *********************************************************************
107    // Interface to package members
108
109    // NOTE: PUBLIC FOR THE MOMENT
110
111    /**
112     * Retrieves a proxy ticket using the PGT that corresponds to the given PGT IOU.
113     */
114    public static String getProxyTicket(String pgtIou, String target) throws IOException {
115        synchronized (ProxyTicketReceptor.class) {
116            // ensure state is sensible
117            if (casProxyUrl == null || pgt == null)
118                throw new IllegalStateException("getProxyTicket() only works after servlet has been initialized");
119        }
120
121        // retrieve PGT
122        String pgtId = null;
123        synchronized (pgt) {
124            pgtId = pgt.get(pgtIou);
125        }
126        if (pgtId == null)
127            return null;
128
129        // retrieve an XML response from CAS's "Proxy" actuator
130        String url = casProxyUrl + "?pgt=" + pgtId + "&targetService=" + target;
131        String response = SecureURL.retrieve(url);
132
133        // parse this response (use a lightweight approach for now)
134        if (response.indexOf("<cas:proxySuccess>") != -1 && response.indexOf("<cas:proxyTicket>") != -1) {
135            int startIndex = response.indexOf("<cas:proxyTicket>") + "<cas:proxyTicket>".length();
136            int endIndex = response.indexOf("</cas:proxyTicket>");
137            return response.substring(startIndex, endIndex);
138        } else {
139            // generic failure
140            return null;
141        }
142    }
143}