1 package org.zxid;
2 
3 /* zxidsrvlet.java  -  SAML SSO Java/Tomcat servlet script that calls libzxid using JNI
4  * Copyright (c) 2007-2009 Symlabs (symlabs@symlabs.com), All Rights Reserved.
5  * Author: Sampo Kellomaki (sampo@iki.fi)
6  * This is confidential unpublished proprietary source code of the author.
7  * NO WARRANTY, not even implied warranties. Contains trade secrets.
8  * Distribution prohibited unless authorized in writing.
9  * Licensed under Apache License 2.0, see file COPYING.
10  * $Id: zxidsrvlet.java,v 1.3 2009-11-20 20:27:13 sampo Exp $
11  * 12.1.2007, created --Sampo
12  * 16.10.2009, refined from zxidhlo example to truly useful servlet that populates session --Sampo
13  *
14  * See also: README-zxid section 10 "zxid_simple() API"
15  */
16 
17 /*
18  * 8.10.2010 , Modified slightly by Stijn Lievens to avoid having to compile
19  * in the configuration string.
20  * Updated to conform (better) to Java conventions.
21  * Removed use of deprecated methods.
22  */
23 
24 import java.io.IOException;
25 import java.net.URLDecoder;
26 
27 import javax.servlet.ServletConfig;
28 import javax.servlet.ServletException;
29 import javax.servlet.http.Cookie;
30 import javax.servlet.http.HttpServlet;
31 import javax.servlet.http.HttpServletRequest;
32 import javax.servlet.http.HttpServletResponse;
33 import javax.servlet.http.HttpSession;
34 
35 import zxidjava.zxidjni;
36 
37 public class ZxidServlet extends HttpServlet {
38 
39 
40   private static final long serialVersionUID = 1L;
41 
42   /**
43    * The ZXID configuration String.
44    */
45   // Maybe this one can be removed.
46   private String conf;  // e.g. "URL=http://zxid-sp.tas3.kent.ac.uk:8080/zxid/sso&PATH=/var/zxid/";
47 
48   /**
49    * The ZXID configuration object.
50    */
51   private zxidjava.zxid_conf cf;
52 
53   /**
54    * Load the ZXID native library.
55    */
56   static {
57     System.loadLibrary("zxidjni");
58   }
59 
60   /**
61    * Does the actual calling of the ZXID native code through {@code zxidjni.simple_cf}.
62    *
63    * @param req
64    * @param res
65    * @param qs
66    * @throws ServletException
67    * @throws IOException
68    */
doZxid(HttpServletRequest req, HttpServletResponse res, String qs)69   private void doZxid(HttpServletRequest req, HttpServletResponse res, String qs)
70       throws ServletException, IOException {
71     if (req.getParameter("gr") != null || req.getParameter("gl") != null) {
72       req.getSession(true).invalidate(); // Invalidate local ses in case of SLO
73     }
74     String ret = zxidjni.simple_cf(cf, -1, qs, null, 0x3d54); // QS response
75                                                               // requested
76     System.err.println(ret);
77     switch (ret.charAt(0)) {
78     case 'L': /* Redirect: ret == "LOCATION: urlCRLF2" */
79       res.sendRedirect(ret.substring(10, ret.length() - 4));
80       return;
81     case '<':
82       switch (ret.charAt(1)) {
83       case 's': /* <se: SOAP envelope */
84       case 'm': /* <m20: metadata */
85         res.setContentType("text/xml");
86         break;
87       default:
88         res.setContentType("text/html");
89         break;
90       }
91       res.setContentLength(ret.length());
92       res.getOutputStream().print(ret);
93       break;
94     case 'z': /* Authorization denied case (if PDP_URL was configured) */
95       System.err.println("Deny (z)");
96       res.sendError(403, "Denied. Authorization to rs(" + req.getParameter("RelayState")
97           + ") was refused by a PDP.");
98       return;
99     case 'd': /* Logged in case (both LDIF and QS will start by "dn") */
100       HttpSession ses = req.getSession(true);
101       String[] avs = ret.split("&");
102       for (int i = 0; i < avs.length; ++i) {
103         String[] av = avs[i].split("=");
104         ses.setAttribute(av[0], URLDecoder.decode(av.length > 1 ? av[1] : "", "UTF-8"));
105       }
106 
107       /*
108        * Make sure cookie is visible to other servlets on the same server.
109        * Alternately you could add emptySessionPath="true" to tomcat
110        * conf/server.xml
111        */
112       Cookie[] cookies = req.getCookies();
113       if (cookies != null) {
114         for (int i = 0; i < cookies.length; i++) {
115           if (cookies[i].getName().equals("JSESSIONID")) { // MUST match cookie
116                                                             // name
117             cookies[i].setPath("/");
118             break;
119           }
120         }
121       }
122 
123       System.err.println("Logged in. jses(" + ses.getId() + ") rs(" + ses.getAttribute("rs") + ")");
124       String rs = URLDecoder.decode(ses.getAttribute("rs").toString(), "UTF-8");
125       if (rs != null && rs.length() > 0 && rs.charAt(rs.length() - 1) != '-') {
126         res.sendRedirect(rs);
127       }
128 
129       /* Redirect was not viable. Just show the management screen. */
130 
131       ret = zxidjni.fed_mgmt_cf(cf, null, -1, ses.getAttribute("sesid").toString(), 0x3d54);
132       res.setContentType("text/html");
133       res.setContentLength(ret.length());
134       res.getOutputStream().print(ret);
135       break;
136     default:
137       System.err.println("Unknown zxid_simple() response(" + ret + ").");
138     }
139   }
140 
141     //@Override
doGet(HttpServletRequest req, HttpServletResponse res)142   public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException,
143       IOException {
144     System.err.print("Start GET...\n");
145     // LECP/ECP PAOS header checks
146     doZxid(req, res, req.getQueryString());
147   }
148 
149     //@Override
doPost(HttpServletRequest req, HttpServletResponse res)150   public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException,
151       IOException {
152     System.err.println("Start POST...");
153     int len = req.getContentLength();
154     byte[] b = new byte[len];
155     int here, got;
156     for (here = 0; here < len; here += got) {
157       got = req.getInputStream().read(b, here, len - here);
158     }
159     String qs = new String(b, 0, len);
160     doZxid(req, res, qs);
161   }
162 
163     //@Override
init(ServletConfig config)164   public void init(ServletConfig config) throws ServletException {
165     if (config.getInitParameter("zxid-configuration") != null) {
166       System.err.println("The zxid-configuration parameter is:"
167           + config.getInitParameter("zxid-configuration"));
168       conf = config.getInitParameter("zxid-configuration");
169     }
170     cf = zxidjni.new_conf_to_cf(conf);
171   }
172 }
173