1<<if: ZXIDBOOK>>
2<<else: >>Net::SAML - Perl Interface to ZXID
3##################################
4<<author: Sampo Kellom�ki (sampo@iki.fi)>>
5<<cvsid: $Id: zxid-perl.pd,v 1.6 2010-01-08 02:10:09 sampo Exp $>>
6<<class: article!a4paper!!ZXID-PERL 01>>
7<<define: ZXDOC=Net::SAML - ZXID Perl Interface>>
8
9<<abstract:
10
11ZXID.org Identity Management toolkit implements standalone SAML 2.0 and
12Liberty ID-WSF 2.0 stacks. This document describes the Perl glue.
13>>
14
15<<maketoc: 1>>
16
171 Introduction
18==============
19
20Perl access to ZXID is using Net::SAML module.
21
22The perl glue for ZXID was generated using swig(1), however, the swig
23interface is not a retrofit: the whole ZXID API was designed to
24be easily swiggifiable.
25
26The main aim of the glue is supporting the easy and simple API, see
27<<link:zxid-simple.html: zxid_simple()>> for general
28reference. Only differences and language specifics are covered in this
29document.
30
311.1 Other documents
32-------------------
33
34<<doc-inc.pd>>
35
366 Net::SAML Perl Module
37=======================
38
39<<fi: >>
40
41* perl CGI example: zxid.pl
42* using with mod_perl
43
44After building the main zxid tree, you can
45
46  cd Net
47  perl Makefile.PL
48  make
49  make test      # Tests are extremely sparse at the moment
50  make install
51
52This assumes you use the pregenerated Net/SAML_wrap.c and Net/SAML.pm files
53that we distribute. If you wish to generate these files from origin,
54you need to have SWIG installed and then say in main zxid directory
55
56  make perlmod ENA_GEN=1  # Makes all available perl modules (including heavy low level ones)
57  make samlmod ENA_GEN=1  # Only makes Net::SAML (much faster)
58  make wsfmod  ENA_GEN=1  # Only makes Net::WSF (much faster)
59
60>  WARNING: Low level interface is baroque, and consequently, it
61>  will take a lot of disk space, RAM and CPU to build it: 100 MB
62>  would not be exaggeration and over an hour (on 1GHz CPU). Build
63>  time memory consumption of single cc1 process will be over
64>  256 MB of RAM. You have been warned.
65
666.1 Example Program (see also zxidhlo.pl)
67-----------------------------------------
68
69<<ignore: perl -ne 'printf "%02d %s", ++$i, $_' <zxidhlo.pl >>
70
71<<logoutput:
7201 use Net::SAML;
7302 $| = 1; undef $/;  # Flush pipes, read all in at once
7403 $url = "http://sp.tas3.pt:8082/zxidhlo.pl";  # Edit to match your situation
7504 $conf = "PATH=/var/zxid/&URL=$url";
7605 $cf = Net::SAML::new_conf_to_cf($conf);
7706 $qs = $ENV{'QUERY_STRING'};
7807 $qs = <STDIN> if $qs =~ /o=P/;
7908 $res = Net::SAML::simple_cf($cf, -1, $qs, undef, 0x1828);
8009 $op = substr($res, 0, 1);
8110 if ($op eq 'L' || $op eq 'C') { print $res; exit; } # LOCATION (Redir) or CONTENT
8211 if ($op eq 'n') { exit; } # already handled
8312 if ($op eq 'e') { my_render_idpsel_screen(); exit; }
8413 if ($op ne 'd') { die "Unknown Net::SAML::simple() res($res)"; }
8514
8615 ($sid) = $res =~ /^sesid: (.*)$/m;  # Extract a useful attribute from SSO output
8716
8817 print <<HTML
8918 CONTENT-TYPE: text/html
9019
9120 <title>ZXID perl HLO SP Mgmt & Protected Content</title>
9221 <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
9322 <link type="text/css" rel=stylesheet href="idpsel.css">
9423 <body bgcolor=white><font face=sans>
9524 $az
9625 <h1>ZXID SP Perl HLO Management & Protected Content (user logged in, session active)</h1>
9726 sesid: $sid
9827 HTML
9928     ;
10029 print Net::SAML::fed_mgmt_cf($cf, undef, -1, $sid, 0x1900);
10130 exit;
10231
10332 sub my_render_idpsel_screen {  # Replaces traditional login screen
10433     print <<HTML;
10534 CONTENT-TYPE: text/html
10635
10736 <title>ZXID SP PERL HLO SSO IdP Selection</title>
10837 <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
10938 <link type="text/css" rel=stylesheet href="idpsel.css">
11039 <body bgcolor=white><font face=sans>
11140 <h1>ZXID SP Perl HLO Federated SSO IdP Selection (user NOT logged in, no session.)</h1>
11241 <form method=get action="zxidhlo.pl">
11342
11443 <h3>Login Using New IdP</h3>
11544
11645 <i>A new IdP is one whose metadata we do not have yet. We need to know
11746 the Entity ID in order to fetch the metadata using the well known
11847 location method. You will need to ask the adminstrator of the IdP to
11948 tell you what the EntityID is.</i>
12049
12150 <p>IdP URL <input name=e size=60><input type=submit name=l2 value=" Login ">
12251 HTML
12352 ;
12453     print Net::SAML::idp_list_cf($cf, undef, 0x1c00);   # Get the IdP selection form
12554     print <<HTML;
12655 <h3>CoT configuration parameters your IdP may need to know</h3>
12756
12857 Entity ID of this SP: <a href="$url?o=B">$url?o=B</a> (Click on the link to fetch SP metadata.)
12958
13059 <input type=hidden name=fc value=1><input type=hidden name=fn value=prstnt>
13160 <input type=hidden name=fq value=""><input type=hidden name=fy value="">
13261 <input type=hidden name=fa value=""><input type=hidden name=fm value="">
13362 <input type=hidden name=fp value=0><input type=hidden name=ff value=0>
13463
13564 </form><hr><a href="http://zxid.org/">zxid.org</a>
13665 HTML
13766     ;
13867 }
139>>
140
141This example only demosntrates SSO.
142
143Lines 1-5 set up the configuration. See zxid-conf.pd for guidance.
144
145ll.6-7 reads in the CGI input the perl way.
146
147l.8 runs the SAML engine of ZXID. The engine will return result that
148is processed below. The magic constant 0x1828 sets some flags, see
149zxid-simple.pd for explanation. This explanation may be especially relevant
150if you plan to run as mod_perl process rather than as a CGI. With
151these flags you could eliminate the need to render the IdP selection
152screen.
153
154ll.9-13: interpret the return value. l.10 deals with parts of SAML
155protocol that need redirect or content. l.12 deals with rendering the
156IdP selection screen. This screen replaces the traditional login
157screen in most applications.
158
159l.15 demonstrates how to extract attributes from the return value. The ret
160is formatted as LDIF so it is very easy to parse with perl.
161
162ll.17-30 render the "protected content". Most protected content should
163contain also Single Logout button. This is accomplished on l.29.
164Protected content is where your normal application after SSO lives.
165You can rely in ZXID session mechanism and just show the content,
166or you could bootstrap your application's session mechanism here.
167
168ll.32-67 render the "idp selection" screen. This could have been
169automatically generated has the flags to Net::SAML::simple_cf()
170been different (see zxid-simple.pd for explanation).
171
172As can be seen, the most central logic for SSO is only about 10 lines. The
173rest is user interface.
174
1756.2 Current major modules are
176-----------------------------
177
178* Net::SAML - The high level interfaces for Single Sign-On (SSO)
179* Net::SAML::Raw - Low level assertion and protocol manipulation interfaces
180* Net::SAML::Metadata - Low level metadata manipulation interfaces
181
1826.3 Planned modules
183-------------------
184
185* Net::WSF - The high level interfaces for Web Services Frameworks (WSF)
186* Net::WSF::Raw - The low level interfaces for WSF variants
187* Net::WSF::WSC - The high level interfaces for Web Services Clients
188* Net::WSF::WSC:Raw
189
1906.4 Perl API Adaptations
191------------------------
192
193The perl APIs were generated from the C .h files using SWIG. Generally any
194C functions and constants that start by zxid_, ZXID_, SAML2_, or SAML_
195have that prefix changed to <<tt: Net::SAML::>>. Note, however, that
196the zx_ prefix is not stripped.
197
198Since ZXID wants to keep strings in many places in length + data
199representation, namely as ~struct zx_str~, SWIG typemaps were used
200to make this happen automatically. Thus any C function that takes as
201an argument <<tt: struct zx_str*>> can take a perl string
202directly. Similarly any C function that returns such a pointer, will
203return a perl string instead. As a final goodie, any C function, such
204as
205
206  struct zx_str* zx_ref_len_str(struct zx_ctx* c, int len, char* s);
207
208that takes ~length~ and <<tt: s>> as explicit arguments, takes only single
209argument that is a perl string (the one argument automatically satisfies
210two C arguments, thanks to a type map). The above could be called like
211
212  $a = Net::SAML::zx_ref_len_str(c, "foo");
213
214First the "foo" satisfies both ~len~ and ~s~, and then the return value
215is converted back to perl string.
216
2176.5 Testing Net::SAML and zxid.pl as CGI script
218-----------------------------------------------
219
220To test the perl module, you must restart the mini_httpd(8) so
221that it recognizes zxid.pl as CGI script:
222
223  mini_httpd -p 8443 -c zxid.pl -S -E zxid.pem
224
225Then start browsing from
226
227  https://sp1.zxidsp.org:8443/zxid.pl
228
229or if you want to avoid the common domain cookie check
230
231  https://sp1.zxidsp.org:8443/zxid.pl?o=E
232
2336.6 Testing Net::SAML and zxid.pl under mod_perl
234------------------------------------------------
235
236You can run zxid.pl under mod_perl using the Apache::Registry
237module. See <<link:apache.html: Apache recipe>> for how
238to compile Apache to support mod_perl. After configuration
239it should work the same as the CGI approach.
240
241<<ignore:
242[Sat Nov 14 12:13:55 2009] [error] [client 127.0.0.1] failed to resolve handler `ModPerl::Registry': Can't locate ModPerl/Registry.pm in @INC (@INC contains: /usr/local/lib/perl5/5.8.4/i686-linux /usr/local/lib/perl5/5.8.4 /usr/local/lib/perl5/site_perl/5.8.4/i686-linux /usr/local/lib/perl5/site_perl/5.8.4 /usr/local/lib/perl5/site_perl . /apps/apache/2.2.3) at (eval 2) line 3.\n
243>>
244
2456.7 Debugging Net::SAML with GDB
246--------------------------------
247
248As bizarre as it may sound, it is actually quite feasible to debug
249libzxid and the SAML_wrap.c using GDB while in perl. For example
250
251  cd zxid
252  gdb /usr/local/bin/perl
253  set env QUERY_STRING=o=E
254  r ./zxid.pl
255
256If the script crashes inside the C code, GDB will perfectly
257reasonably take control, allowing you to see stack back-trace (bt)
258and examine variables. Of course it helps if openssl and perl
259were compiled with debug symbols (libzxid is compiled
260with debug symbols by default), but even if they weren't you
261can usually at least get some clue.
262
263When preparing a perl module, generally Makefile.PL mechanism causes
264the same compilation flags to be used as were used to compile the perl
265itself. Generally this is good, but if libzxid was compiled with
266different flags, mysterious errors can crop up. For example, I compile
267my libzxid against openssl that I have also compiled myself. However, I
268once had a bug where the perl had been compiled such that the Linux
269distribution's incompatible openssl would be picked by perl compile
270flags, resulting in mystery crashes deep inside openssl ASN.1 decoder
271routines (c2i_ASN1_INTEGER() while in d2i_X509() to be exact). When I
272issued `info files' in GDB I finally realized that I was using the
273wrong openssl library.
274
275<<if: ZXIDBOOK>>
276<<else: >>
277
27896 License
279==========
280
281Copyright (c) 2010 Sampo Kellom�ki (sampo@iki.fi), All Rights Reserved.
282
283Copyright (c) 2006-2009 Symlabs (symlabs@symlabs.com), All Rights Reserved.
284Author: Sampo Kellom�ki (sampo@iki.fi)
285
286See file COPYING for complete information.
287
28897 FAQ extract
289==============
290
291See zxid-faq.pd for full story.
292
29397.1 Compilation Problems
294-------------------------
295
29697.1.4 Perl compiled with different compiler than zxid
297~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
298
299(*** also appears in README.zxid FAQ)
300
301Perl modules generally want to be compiled with the same C compiler
302and options as were used to compile perl itself (see perl -V). If this
303happens to be different than the compiler you have defined in CC
304variable (gcc by default, near top of Makefile or in localconf.mk), you may
305get an error like:
306
307  cd Net; perl Makefile.PL && make
308  Warning: -L.. changed to -L/home/sampo/zxid/Net/..
309  Writing Makefile for Net::SAML
310  make[1]: Entering directory `/home/sampo/zxid/Net'
311  cc -c  -I.. -I/apps/openssl/std/include -I/apps/include -D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBUGGING -fno-strict-aliasing -pipe -Wdeclaration-after-statement -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 -march=i586 -mtune=i686 -fmessage-length=0 -Wall -D_FORTIFY_SOURCE=2 -g -Wall -pipe   -DVERSION=\"\" -DXS_VERSION=\"\" -fPIC "-I/usr/lib/perl5/5.8.8/i586-linux-thread-multi/CORE"   SAML_wrap.c
312  /bin/sh: cc: command not found
313  make[1]: *** [SAML_wrap.o] Error 127
314  make[1]: Leaving directory `/zxid/Net'
315  make: *** [samlmod] Error 2
316
317*Solutions*
318
3191. Compile zxid with compiler that was used for perl, e.g.
320
321     make CC=the-compiler-that-perl-wants
322
3232. Recompile perl using the compiler that you want to use for zxid
324
3253. Tinker with PATH environment variable so that both C compilers
326   are found. However, using two different compilers is not really supported.
327
328In general these types of problems happen when you use perl installed
329by your distribution, but have later compiled a gcc of your own. It may
330even be that you never installed the distribution cc - in that case
331consider installing it and then trying approaches 1 or 3.
332
333A similar situation can arise with incompatibility of the compiler and
334options used for dependency libraries, such as OpenSSL or libcurl, and
335those used for compiling zxid itself.
336
33797.1.5 All files under zx missing
338~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
339
340(*** also appears in README.zxid FAQ)
341
342You need to symlink zx to zxid source directory, thus
343
344  ln -s . zx
345
346If you do not have it, then you will get a lot of file inclusion errors for
347headers that are supposed to be in path starting by zx/
348
349The symlink is there to keep all hand written source files on top
350level of directory for ease of development, yet allow inclusions to go
351through ~zx~ subdirectory. When zxid is installed, it goes to
352/usr/include/zx. Hence the symlink keeps the includes the same whether
353developing or using installed version.
354
35597.1.6 Compiler Warnings
356~~~~~~~~~~~~~~~~~~~~~~~~
357
358(*** also appears in README.zxid FAQ)
359
360If you compile zxid with compiler warnings turned on (CFLAGS += -Wall),
361you will see quite a number of warnings, most of which are
362unwarranted. Since the warnings are unwarranted, I ship zxid Makefile
363with warnings turned off. If this bothers you, feel free to investigate
364the warnings and report to me any issues you uncover.
365
366Following warnings in partuclar are unwarranted:
367
3681. Any unusued variable warnings, especially in generated code. Most
369   common of these is ~se~ variable (see enc-templ.c).
3702. "Suggest parenthesis around assignment when used as truth value." I
371   rely on C language operator precedence. Also, in most cases the
372   assignment is the only expression in the truth test - there simply
373   is no opportunity for ambiguity -- and no justified case for gcc to
374   warn about this.
3753. "Suggest parenthesis around && when used in ||". I rely on C
376   language operator precedence, hence the suggestion is redundant.
377
378Some warnings you may want to worry about
379
380A. "int format, long int arg". On 32 bit platforms int and long
381   are both 32 bits so this warning is not an issue. On 64 bit platforms,
382   however, there may be cause for worry.
383
38497.1.8 SWIG and Perl Problems
385~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
386
387ZXID is tested and known to work with SWIG version 1.3.40. It is known not
388to work with SWIG-2.0.4. The telltale sign is
389
390  perl -MNet::SAML -e 'print Net::SAML::call($cf,$ses,$svctype,$url,0,0,$soap)'
391  TypeError in method 'zxid_call', argument 5 of type 'char const *'
392
393SWIG version should not be a concern for those using .tgz distributions of
394ZXID as the tar gzip archives already contain the files generated by SWIG.
395Also installs from cpan should not be affected.
396
397<<references:
398
399[SAML2core] "Assertions and Protocols for the OASIS Security Assertion Markup Language (SAML) V2.0", Oasis Standard, 15.3.2005, saml-core-2.0-os
400
401
402>>
403
404<<doc-end.pd>>
405<<notapath: TCP/IP a.k.a xBSD/Unix n/a Perl/mod_perl PHP/mod_php Java/Tomcat>>
406<<EOF: >>
407<<fi: >>