1=head1 NAME
2
3Net::SAML - Perl extension for using SAML SSO
4
5=head1 SYNOPSIS
6
7  use Net::SAML;
8
9  $cf = Net::SAML::new_conf("/var/zxid/");
10  Net::SAML::url_set($cf, $url);
11  Net::SAML::set_opt($cf, 1 ,1);  # Turn on libzxid level debugging
12
13  $res = Net::SAML::simple_cf($cf, -1, $qs, undef, 0x1828);  # The main API
14
15  # Low level API (do not use without first understanding Net::SAML::simple_cf()
16
17  $cgi = Net::SAML::new_cgi($cf, $ENV{'QUERY_STRING'});
18  $sid = Net::SAML::zxid_cgi::swig_sid_get($cgi);
19  $ses = Net::SAML::fetch_ses($cf, $sid);
20
21  Net::SAML::parse_cgi($cgi, $qs);
22  $op = Net::SAML::zxid_cgi::swig_op_get($cgi);
23
24  $ses = Net::SAML::fetch_ses($cf, "");  # Just allocate an empty one
25  Net::SAML::del_ses($cf, $ses);
26  $sid = Net::SAML::zxid_ses::swig_sid_get($ses);
27  $nid = Net::SAML::zxid_ses::swig_nid_get($ses);
28
29  Net::SAML::lecp_check($cf, $cgi);
30  Net::SAML::cdc_read($cf, $cgi);
31
32  $url = Net::SAML::start_sso_url($cf, $cgi);
33  $ret = Net::SAML::sp_deref_art($cf, $cgi, $ses);
34
35  $req = Net::SAML::zxid_cgi::swig_saml_req_get($cgi);
36  $res = Net::SAML::zxid_cgi::swig_saml_resp_get($cgi);
37  $ret = Net::SAML::sp_dispatch($cf, $cgi, $ses, $res);
38
39  Net::SAML::send_sp_meta($cf, $cgi);
40  $idp = Net::SAML::load_cot_cache($cf);
41  $eid = Net::SAML::zxid_entity::swig_eid_get($idp);
42  $eid_len = Net::SAML::zxid_entity::swig_eid_len_get($idp);
43  $idp = Net::SAML::zxid_entity::swig_n_get($idp);
44
45  Net::SAML::sp_slo_redir($cf, $cgi, $ses);
46  Net::SAML::sp_slo_soap($cf, $cgi, $ses);
47
48  Net::SAML::sp_nireg_redir($cf, $cgi, $ses, 0);
49  Net::SAML::sp_nireg_soap($cf, $cgi, $ses, 0);
50
51  Net::SAML::OK;
52  Net::SAML::REDIR_OK;
53
54=head1 EXAMPLE
55
56You should see zxid-perl.pd, zxid-simple.pd, and zxid-conf.pd for more complete
57documentation. Here is a quick walk through of a typical SP usage:
58
59  01 use Net::SAML;
60  02 $| = 1; undef $/;  # Flush pipes, read all in at once
61  03 $url = "http://sp.tas3.pt:8082/zxidhlo.pl";  # Edit to match your situation
62  04 $conf = "PATH=/var/zxid/&URL=$url";
63  05 $cf = Net::SAML::new_conf_to_cf($conf);
64  06 $qs = $ENV{'QUERY_STRING'};
65  07 $qs = <STDIN> if $qs =~ /o=P/;
66  08 $res = Net::SAML::simple_cf($cf, -1, $qs, undef, 0x1828);
67  09 $op = substr($res, 0, 1);
68  10 if ($op eq 'L' || $op eq 'C') { print $res; exit; } # LOCATION (Redir) or CONTENT
69  11 if ($op eq 'n') { exit; } # already handled
70  12 if ($op eq 'e') { my_render_idpsel_screen(); exit; }
71  13 if ($op ne 'd') { die "Unknown Net::SAML::simple() res($res)"; }
72  14
73  15 ($sid) = $res =~ /^sesid: (.*)$/m;  # Extract a useful attribute from SSO output
74  16
75  17 print <<HTML
76  18 CONTENT-TYPE: text/html
77  19
78  20 <title>ZXID perl HLO SP Mgmt & Protected Content</title>
79  21 <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
80  22 <link type="text/css" rel=stylesheet href="idpsel.css">
81  23 <body bgcolor=white><font face=sans>
82  24
83  25 <h1>ZXID SP Perl HLO Management & Protected Content (user logged in, session active)</h1>
84  26 sesid: $sid
85  27 HTML
86  28     ;
87  29 print Net::SAML::fed_mgmt_cf($cf, undef, -1, $sid, 0x1900);
88  30 exit;
89  31
90  32 sub my_render_idpsel_screen {  # Replaces traditional login screen
91  33     print <<HTML;
92  34 CONTENT-TYPE: text/html
93  35
94  36 <title>ZXID SP PERL HLO SSO IdP Selection</title>
95  37 <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
96  38 <link type="text/css" rel=stylesheet href="idpsel.css">
97  39 <body bgcolor=white><font face=sans>
98  40 <h1>ZXID SP Perl HLO Federated SSO IdP Selection (user NOT logged in, no session.)</h1>
99  41 <form method=get action="zxidhlo.pl">
100  42
101  43 <h3>Login Using New IdP</h3>
102  44
103  45 <i>A new IdP is one whose metadata we do not have yet. We need to know
104  46 the Entity ID in order to fetch the metadata using the well known
105  47 location method. You will need to ask the adminstrator of the IdP to
106  48 tell you what the EntityID is.</i>
107  49
108  50 <p>IdP URL <input name=e size=60><input type=submit name=l2 value=" Login ">
109  51 HTML
110  52 ;
111  53     print Net::SAML::idp_list_cf($cf, undef, 0x1c00);   # Get the IdP selection form
112  54     print <<HTML;
113  55 <h3>CoT configuration parameters your IdP may need to know</h3>
114  56
115  57 Entity ID of this SP: <a href="$url?o=B">$url?o=B</a> (Click on the link to fetch SP metadata.)
116  58
117  59 <input type=hidden name=fc value=1><input type=hidden name=fn value=prstnt>
118  60 <input type=hidden name=fq value=""><input type=hidden name=fy value="">
119  61 <input type=hidden name=fa value=""><input type=hidden name=fm value="">
120  62 <input type=hidden name=fp value=0><input type=hidden name=ff value=0>
121  63
122  64 </form><hr><a href="http://zxid.org/">zxid.org</a>
123  65 HTML
124  66     ;
125  67 }
126
127This example only demosntrates SSO.
128
129Lines 1-5 set up the configuration. See zxid-conf.pd for guidance.
130
131ll.6-7 reads in the CGI input the perl way.
132
133l.8 runs the SAML engine of ZXID. The engine will return result that
134is processed below. The magic constant 0x1828 sets some flags, see
135zxid-simple.pd for explanation. This explanation may be especially relevant
136if you plan to run as mod_perl process rather than as a CGI. With
137these flags you could eliminate the need to render the IdP selection
138screen.
139
140ll.9-13: interpret the return value. l.10 deals with parts of SAML
141protocol that need redirect or content. l.12 deals with rendering the
142IdP selection screen. This screen replaces the traditional login
143screen in most applications.
144
145l.15 demonstrates how to extract attributes from the return value. The ret
146is formatted as LDIF so it is very easy to parse with perl.
147
148ll.17-30 render the "protected content". Most protected content should
149contain also Single Logout button. This is accomplished on l.29.
150Protected content is where your normal application after SSO lives.
151You can rely in ZXID session mechanism and just show the content,
152or you could bootstrap your application's session mechanism here.
153
154ll.32-67 render the "idp selection" screen. This could have been
155automatically generated has the flags to Net::SAML::simple_cf()
156been different (see zxid-simple.pd for explanation).
157
158As can be seen, the most central logic for SSO is only about 10 lines. The
159rest is user interface.
160
161=head1 DESCRIPTION
162
163See zxid/zxid.pl for example use of this module.
164
165Consult zxid/README.zxid for detailed API descriptions. This
166pod is only a place holder - real documentation is in
167the README.zxid file.
168
169=head1 ZXID
170
171The above synopsis is just a tip of the iceberg. Net::SAML
172is part of a bigger project called ZXID. The code for the
173Net::SAML module was automagically generated from schema grammar
174sources and C header files of that project using SWIG.
175
176See http://zxid.org and zxid/README.zxid for further information.
177
178=head1 DIAGNOSTICS
179
180"Random number generator not seeded!!!"
181  This warning indicates that randomize() was not able to read
182  /dev/random or /dev/urandom, possibly because your system does not
183  have them or they are differently named. You can still use SSL, but
184  the encryption will not be as strong. Investigate setting up
185  EGD (entropy gathering daemon) or PRNG (Pseudo Random Number
186  Generator). Both are available on the net.
187
188"msg 123: 1 - error:140770F8:SSL routines:SSL23_GET_SERVER_HELLO:unknown proto"
189  SSLeay error string. First (123) number is PID, second number (1) indicates
190  the position of the error message in SSLeay error stack. You often see
191  a pile of these messages as errors cascade.
192
193"msg 123: 1 - error:02001002::lib(2) :func(1) :reason(2)"
194  The same as above, but you didn't call load_error_strings() so SSLeay
195  couldn't verbosely explain the error. You can still find out what it
196  means with this command:
197
198     /usr/local/ssl/bin/ssleay errstr 02001002
199
200Password is being asked for private key
201  This is normal behaviour if your private key is encrypted. Either
202  you have to supply the password or you have to use unencrypted
203  private key. Scan OpenSSL.org for the FAQ that explains how to
204  do this.
205
206=head1 AUTHOR
207
208Sampo Kellom�ki <sampo@iki.fi>
209
210Please send well researched bug reports to the above address.
211General questions should be sent to me as well.
212
213=head1 VERSION
214
215This page documents version 0.5, as of 14.9.2006.
216
217=head1 COPYRIGHT
218
219Copyright (c) 2006 Sampo Kellom�ki <sampo@symlabs.com>
220All Rights Reserved.
221
222Licensed under the Apache License, Version 2.0 (the "License");
223you may not use this file except in compliance with the License.
224You may obtain a copy of the License at
225http://www.apache.org/licenses/LICENSE-2.0
226
227Unless required by applicable law or agreed to in writing, software
228distributed under the License is distributed on an "AS IS" BASIS,
229WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
230See the License for the specific language governing permissions and
231limitations under the License.
232
233While the source distribution of this perl module does not contain
234SSLeay or OpenSSL code, if you use this module you will use OpenSSL
235library. Please give Eric Young and OpenSSL team credit (as required by
236their licenses).
237
238And remember, you, and nobody else but you, are responsible for
239auditing this module and OpenSSL library for security problems,
240backdoors, and general suitability for your application.
241
242=head1 SEE ALSO
243
244  Net::WSF  -  Related perl module for ID Web Services Framework
245  <http://zxid.org/>  - ZXID Project home
246  <http://www.openssl.org/>                - OpenSSL source, documentation, etc
247  <http://www.w3c.org>                     - HTTP specifications
248  <http://www.ietf.org/rfc/rfc2617.txt>    - How to send password
249  <http://www.lothar.com/tech/crypto/>     - Entropy Gathering Daemon (EGD)
250  <http://www.aet.tu-cottbus.de/personen/jaenicke/postfix_tls/prngd.html>
251                           - pseudo-random number generating daemon (PRNGD)
252
253=cut
254