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