1<? 2# zxid/zxid.php - Implement SAML SP role in PHP using zxid extension 3# 4# Copyright (c) 2006-2008 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: zxid.php,v 1.8 2008-05-26 15:28:44 sampo Exp $ 11# 31.8.2006, created --Sampo 12# 15.9.2006, enhanced to actually support SSO --Sampo 13# 5.3.2007, double checked and fixed to work against 0.16 --Sampo 14# 25.5.2008, fixed to work against 0.27, fixed port number to 5443 --Sampo 15 16dl("php_zxid.so"); 17 18$cf = zxid_new_conf("/var/zxid/"); 19$path = zxid_conf_path_get($cf); # *** Weird: without "get" the cf->path is screwed?!? 20#$path_len = zxid_conf_path_len_get($cf); 21#error_log("path($path) len($len)", 0); 22 23$url = "https://sp1.zxidsp.org:5443/zxid.php"; 24$cdc_url = "https://sp1.zxidcommon.org:5443/zxid.php"; # zxid_my_cdc_url() 25zxid_url_set($cf, $url); 26zxid_set_opt($cf, 1 ,1); # Turn on libzxid level debugging 27$cgi = zxid_new_cgi($cf, $_SERVER['QUERY_STRING']); 28$op = zxid_cgi_op_get($cgi); 29error_log("op($op)", 0); 30if ($op == 'P') { 31 $qs = file_get_contents('php://input'); # better than $HTTP_RAW_POST_DATA 32 error_log("raw post($qs)", 0); 33 zxid_parse_cgi($cgi, $qs); 34 $op = zxid_cgi_op_get($cgi); 35} 36if (!$op) $op = 'M'; 37 38function mgmt_screen($cf, $cgi, $ses, $op) 39{ 40 error_log("mgmt op($op)", 0); 41 switch ($op) { 42 case 'l': 43 zxid_del_ses($cf, $ses); 44 $msg = "Local logout Ok. Session terminated."; 45 return 0; # Simply abandon local session. Falls thru to login screen. 46 case 'r': 47 $loc = zxid_sp_slo_location($cf, $cgi, $ses); 48 zxid_del_ses($cf, $ses); 49 header($loc); 50 return 1; # Redirect already happened. Do not show login screen. 51 case 's': 52 zxid_sp_slo_soap($cf, $cgi, $ses); 53 zxid_del_ses($cf, $ses); 54 $msg = "SP Initiated logout (SOAP). Session terminated."; 55 return 0; # Falls thru to login screen. 56 case 't': 57 $loc = zxid_sp_nireg_location($cf, $cgi, $ses, 0); 58 header($loc); 59 return 1; # Redirect already happened. Do not show login screen. 60 case 'u': 61 zxid_sp_nireg_soap($cf, $cgi, $ses, 0); 62 $msg = "SP Initiated defederation (SOAP)."; 63 break; 64 case 'P': 65 $ret = zxid_sp_dispatch($cf, $cgi, $ses, zxid_cgi_saml_resp_get($cgi)); 66 switch ($ret) { 67 case ZXID_OK: return 0; 68 case ZXID_REDIR_OK: return 1; 69 } 70 break; 71 case 'Q': 72 $ret = zxid_sp_dispatch($cf, $cgi, $ses, zxid_cgi_saml_req_get($cgi)); 73 switch ($ret) { 74 case ZXID_OK: return 0; 75 case ZXID_REDIR_OK: return 1; 76 } 77 break; 78 } 79 80 $sid = zxid_ses_sid_get($ses); 81 $nid = zxid_ses_nid_get($ses); 82 83 # In gimp flatten the image and Save Copy as pnm 84 # giftopnm favicon.gif | ppmtowinicon >favicon.ico 85 #printf("COOKIE: foo\r\n"); 86?> 87<title>ZXID SP Mgmt PHP</title> 88<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" /> 89<body bgcolor="#330033" text="#ffaaff" link="#ffddff" vlink="#aa44aa" alink="#ffffff"><font face=sans> 90 91<h1>ZXID SP Management PHP (user logged in, session active)</h1><pre> 92</pre><form method=post action="zxid.php?o=P"> 93<input type=hidden name=s value="<?=$sid?>"> 94<input type=submit name=gl value=" Local Logout "> 95<input type=submit name=gr value=" Single Logout (Redir) "> 96<input type=submit name=gs value=" Single Logout (SOAP) "> 97<input type=submit name=gt value=" Defederate (Redir) "> 98<input type=submit name=gu value=" Defederate (SOAP) "> 99 100<h3>Technical options (typically hidden fields on production site)</h3> 101 102sid(<?=$sid?>) nid(<?=$nid?>) <a href="zxid.php?s=<?=$sid?>">Reload</a> 103 104</form><hr> 105<a href="http://zxid.org/">zxid.org</a> 106<? 107 return 1; 108} 109 110$sid = zxid_cgi_sid_get($cgi) 111 and $ses = zxid_fetch_ses($cf, $sid) 112 and mgmt_screen($cf, $cgi, $ses, $op) 113 and exit; 114$ses = zxid_fetch_ses($cf, ""); # Just allocate an empty one 115 116error_log("Not logged-in case: op($op) ses($ses)", 0); 117 118switch ($op) { 119case 'M': # Invoke LECP or redirect to CDC reader. 120 #if (zxid_lecp_check($cf, $cgi)) exit; 121 header("Location: $cdc_url?o=C"); 122 exit; 123case 'C': # CDC Read: Common Domain Cookie Reader 124 zxid_cdc_read($cf, $cgi); 125 exit; 126case 'E': # Return from CDC read, or start here to by-pass CDC read. 127 #if (zxid_lecp_check($cf, $cgi)) exit; 128 if (zxid_cdc_check($cf, $cgi)) exit; 129 break; 130case 'L': 131 error_log("Start login", 0); 132 $loc = zxid_start_sso_location($cf, $cgi); 133 if ($loc) { 134 error_log("login redir($loc)", 0); 135 header($loc); 136 exit; 137 } 138 error_log("Login trouble", 0); 139 break; 140case 'A': 141 $ret = zxid_sp_deref_art($cf, $cgi, $ses); 142 error_log("deref art ret($ret)", 0); 143 if ($ret == ZXID_REDIR_OK) exit; 144 if ($ret == ZXID_SSO_OK) 145 if (mgmt_screen($cf, $cgi, $ses, $op)) 146 exit; 147 break; 148case 'P': 149 $ret = zxid_sp_dispatch($cf, $cgi, $ses, zxid_cgi_saml_resp_get($cgi)); 150 error_log("saml_resp ret($ret)", 0); 151 if ($ret == ZXID_REDIR_OK) exit; 152 if ($ret == ZXID_SSO_OK) 153 if (mgmt_screen($cf, $cgi, $ses, $op)) 154 exit; 155 break; 156case 'Q': 157 $ret = zxid_sp_dispatch($cf, $cgi, $ses, zxid_cgi_saml_req_get($cgi)); 158 if ($ret == ZXID_REDIR_OK) exit; 159 if ($ret == ZXID_SSO_OK) 160 if (mgmt_screen($cf, $cgi, $ses, $op)) 161 exit; 162 break; 163case 'B': 164 header("CONTENT-TYPE: text/xml"); 165 $md = zxid_sp_meta($cf, $cgi); 166 echo $md; 167 exit; 168default: 169 error_log("Unknown op($op)", 0); 170} 171 172?> 173<title>ZXID SP SSO PHP</title> 174<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" /> 175<body bgcolor="#330033" text="#ffaaff" link="#ffddff" vlink="#aa44aa" alink="#ffffff"><font face=sans><h1>ZXID SP Federated SSO PHP (user NOT logged in, no session.)</h1><pre> 176</pre><form method=post action="zxid.php?o=P"> 177 178<h3>Login Using New IdP</h3> 179 180<i>A new IdP is one whose metadata we do not have yet. We need to know 181the Entity ID in order to fetch the metadata using the well known 182location method. You will need to ask the adminstrator of the IdP to 183tell you what the EntityID is.</i> 184 185<p>IdP EntityID URL <input name=e size=60> 186<input type=submit name=l1 value=" Login (SAML20:Artifact) "> 187<input type=submit name=l2 value=" Login (SAML20:POST) "> 188<? 189 190$idp = zxid_load_cot_cache($cf); 191if ($idp) { 192 echo "<h3>Login Using Known IdP</h3>\n"; 193 while ($idp) { 194 $eid = zxid_entity_eid_get($idp); 195 $eid_len = zxid_entity_eid_len_get($idp); 196 $eid = substr($eid, 0, $eid_len); 197 error_log("eid_len($eid_len) eid($eid)", 0); 198 echo <<< HTML 199<input type=submit name="l1$eid" value=" Login to $eid (SAML20:Artifact) "> 200<input type=submit name="l2$eid" value=" Login to $eid (SAML20:POST) "> 201HTML; 202 $idp = zxid_entity_n_get($idp); 203 } 204} 205 206$version_str = zxid_version_str(); 207 208?> 209<h3>CoT configuration parameters your IdP may need to know</h3> 210 211Entity ID of this SP: <a href="<?=$url?>?o=B"><?=$url?>?o=B</a> (Click on the link to fetch SP metadata.) 212 213<h3>Technical options (typically hidden fields on production site)</h3> 214 215<input type=checkbox name=fc value=1 checked> Allow new federation to be created<br> 216<input type=checkbox name=fp value=1> Do not allow IdP to interact (e.g. ask password) (IsPassive flag)<br> 217<input type=checkbox name=ff value=1> IdP should reauthenticate user (ForceAuthn flag)<br> 218NID Format: <select name=fn><option value=prstnt>Persistent<option value=trnsnt>Transient<option value="">(none)</select><br> 219Affiliation: <select name=fq><option value="">(none)</select><br> 220 221Consent: <select name=fy><option value="">(empty) 222<option value="urn:liberty:consent:obtained">obtained 223<option value="urn:liberty:consent:obtained:prior">obtained:prior 224<option value="urn:liberty:consent:obtained:current:implicit">obtained:current:implicit 225<option value="urn:liberty:consent:obtained:current:explicit">obtained:current:explicit 226<option value="urn:liberty:consent:unavailable">unavailable 227<option value="urn:liberty:consent:inapplicable">inapplicable 228</select><br> 229Authn Req Context: <select name=fa><option value="">(none) 230<option value=pw>Password 231<option value=pwp>Password with Protected Transport 232<option value=clicert>TLS Client Certificate</select><br> 233Matching Rule: <select name=fm><option value=exact>Exact 234<option value=minimum>Min 235<option value=maximum>Max 236<option value=better>Better 237<option value="">(none)</select><br> 238 239</form><hr><a href="http://zxid.org/">zxid.org</a>, <?=$version_str?> 240