1 /* zxidwspleaf.java  -  Demonstrate server side of handling a web service call
2  * Copyright (c) 2012 Synergetics (sampo@synergetics.be), All Rights Reserved.
3  * Copyright (c) 2010-2011 Sampo Kellomaki (sampo@iki.fi), All Rights Reserved.
4  * Copyright (c) 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: zxidappdemo.java,v 1.3 2009-11-20 20:27:13 sampo Exp $
11  * 16.10.2009, created --Sampo
12  * 16.2.2010, fixed virtual hosting --Sampo
13  * 7.2.2012, new virtual hosting with <init-param> supplied config --Sampo
14  *
15  * See also: zxid-java.pd, zxidappdemo.java for client side
16  *
17  * Discovery registration:
18  *   ./zxcot -e http://sp.tas3.pt:8080/zxidservlet/wspdemo 'TAS3 WSP Demo' http://sp.tas3.pt:8080/zxidservlet/wspdemo?o=B urn:x-foobar | ./zxcot -d -b /var/zxid/idpdimd
19  *   touch /var/zxid/idpuid/.all/.bs/urn_x-foobar,l9O3xlWWi9kLZm-yQYRytpf0lqw
20  */
21 
22 import zxidjava.*;   // Pull in the zxidjni.az() API
23 import java.io.*;
24 import javax.servlet.*;
25 import javax.servlet.http.*;
26 
27 public class zxidwspleaf extends HttpServlet {
28     static zxidjava.zxid_conf cf = null;
29     static { System.loadLibrary("zxidjni"); }
30 
init_zxid_vhost(HttpServletRequest req)31     public void init_zxid_vhost(HttpServletRequest req)
32 	throws ServletException
33     {
34 	// CONFIG: You must have created /var/zxid directory hierarchy. See `make dir'
35 	// CONFIG: To set config string, edit web.xml (hope you know where it is) and
36 	// add to your servlets sections like
37         //  <servlet>
38 	//    <servlet-name>zxidsrvlet</servlet-name><servlet-class>zxidsrvlet</servlet-class>
39 	//    <init-param>
40 	//      <param-name>ZXIDConf</param-name><param-value>PATH=/var/zxid/</param-value>
41 	//    </init-param>
42 	//  </servlet>
43 	// CONFIG: You must edit the URL to match your domain name and port, usually you
44 	// CONFIG: would create and edit /var/zxid/zxid.conf and override the URL there.
45 	// CONFIG: However, this program sets the URL dynamically, see calls to zxidjni.url_set()
46 	if (cf == null) {
47 	    String conf = getServletConfig().getInitParameter("ZXIDConf");
48 	    cf = zxidjni.new_conf_to_cf(conf);
49 	    zxidjni.set_opt(cf, 1, 1);  // Debug on
50 	    zxidjni.set_opt(cf, 7, 3);  // Cause glibc malloc/free to dump core on error
51 	}
52 	String scheme = req.getScheme();
53 	String host_hdr = req.getHeader("HOST");
54 	String fullURL = req.getRequestURI();
55 	String url = scheme + "://" + host_hdr + fullURL;
56 	System.err.print("url("+url+")\n");  // URL=http://sp.tas3.pt:8080/zxidservlet/wspdemo
57 	zxidjni.url_set(cf, url);  // Virtual host support
58     }
59 
60     // Only reason why a pure WSP would handle GET is supporting WKL metadata
61     // exchange (o=B). However, a hybrid frontend SP plus WSP would handle its SSO here.
62 
doGet(HttpServletRequest req, HttpServletResponse res)63     public void doGet(HttpServletRequest req, HttpServletResponse res)
64 	throws ServletException, IOException
65     {
66 	System.err.print("Start GET...\n");
67 	init_zxid_vhost(req);
68 	String qs = req.getQueryString();
69 	if (qs != null && qs.equals("o=B")) {  // Metadata check
70 	    String ret = zxidjni.simple_cf(cf, -1, qs, null, 0x3d54);  // QS response requested
71 	    System.err.print(ret);
72 	    switch (ret.charAt(0)) {
73 	    case 'L':  /* Redirect: ret == "LOCATION: urlCRLF2" */
74 		res.sendRedirect(ret.substring(10, ret.length() - 4));
75 		return;
76 	    case '<':
77 		switch (ret.charAt(1)) {
78 		case 's': case 'm': res.setContentType("text/xml"); break; /* <m20: metadata ... */
79 		default:	    res.setContentType("text/html"); break;
80 		}
81 		res.setContentLength(ret.length());
82 		res.getOutputStream().print(ret);
83 		break;
84 	    default:
85 		System.err.print("Unhandled zxid_simple() response("+ret+").\n");
86 	    }
87 	    return;
88 	}
89 
90 	res.setContentType("text/html");
91 	res.getOutputStream().print("<title>ZXID Leaf WSP</title><body><h1>ZXID Leaf WSP does not offer web GUI (" + req.getRequestURI() + ")</H1>\n<pre>"+qs+"</pre>");
92     }
93 
94     // Handle a SOAP call, which is always a POST
95 
doPost(HttpServletRequest req, HttpServletResponse res)96     public void doPost(HttpServletRequest req, HttpServletResponse res)
97 	throws ServletException, IOException
98     {
99 	String ret;
100 	System.err.print("\n============ LEAF WSP Start SOAP POST ============\n");
101 	init_zxid_vhost(req);
102 	zxidjava.zxid_ses ses = zxidjni.alloc_ses(cf);
103 
104 	// Java / Servlet complicated way of reading in the POST input
105 
106 	String buf;
107 	int len = req.getContentLength();
108 	byte[] b = new byte[len];
109 	int here, got;
110 	for (here = 0; here < len; here += got)
111 	    got = req.getInputStream().read(b, here, len - here);
112 	buf = new String(b, 0, len);
113 
114 	// Simulate deny
115 
116 	System.err.print("HERE1\n");
117 	zxidjni.set_tas3_status(cf, ses, zxidjni.mk_tas3_status(cf, null, "urn:tas3:ctlpt:app", "urn:tas3:status:deny", null, null, null));
118 	System.err.print("HERE 2\n");
119 
120 	// Check the input for correct ID-WSF compliance
121 
122 	zxidjni.set_opt(cf, 7, 3);  // Cause glibc malloc/free to dump core on error
123 	//System.err.print("Validating buf("+buf+")\n");
124 	String nid  = zxidjni.wsp_validate(cf, ses, "Resource=leaf", buf);
125 	System.err.print("VALID3 nid("+nid+")\n");
126 	if (nid == null) {
127 	    System.err.print("Validate fail buf("+buf+")\n");
128 	    ret = zxidjni.wsp_decorate(cf, ses, "Resource=leaf:fail",
129 				       "<recursed>"
130 				       + "<lu:Status code=\"Fail\" comment=\"INVALID. Token replay?\"></lu:Status>" +
131 				       "</recursed>");
132 	    res.getOutputStream().print(ret);
133 	    System.err.print("^^^^^^^^^^^^^ WSP inval ("+ret.length()+" chars output) ^^^^^^^^^^^^^\n\n");
134 	    return;
135 	}
136 	String ldif = zxidjni.ses_to_ldif(cf, ses);
137 	System.err.print("\n===== Leaf Doing work for user nid("+nid+").\nLDIF: "+ldif+"\n");
138 
139 	ret = zxidjni.wsp_decorate(cf, ses, "Resource=leaf",
140 				   "<recursed>"
141 				   + "<lu:Status code=\"OK\">ok</lu:Status>"
142 				   + "<data>nid="+nid+"\n"+ldif+"\n</data>" +
143 				   "</recursed>");
144 
145 	res.getOutputStream().print(ret);
146 	System.err.print("^^^^^^^^^^^^^ LEAF WSP Done ("+ret.length()+" chars output) ^^^^^^^^^^^^^\n\n");
147     }
148 }
149 
150 /* EOF */
151