00001 <?php
00002
00007 require_once "Auth/OpenID.php";
00008 require_once "Auth/OpenID/Parse.php";
00009 require_once "Auth/OpenID/Message.php";
00010 require_once "Auth/Yadis/XRIRes.php";
00011 require_once "Auth/Yadis/Yadis.php";
00012
00013
00014 define('Auth_OpenID_XMLNS_1_0', 'http://openid.net/xmlns/1.0');
00015
00016
00017 define('Auth_OpenID_TYPE_1_2', 'http://openid.net/signon/1.2');
00018 define('Auth_OpenID_TYPE_1_1', 'http://openid.net/signon/1.1');
00019 define('Auth_OpenID_TYPE_1_0', 'http://openid.net/signon/1.0');
00020 define('Auth_OpenID_TYPE_2_0_IDP', 'http://specs.openid.net/auth/2.0/server');
00021 define('Auth_OpenID_TYPE_2_0', 'http://specs.openid.net/auth/2.0/signon');
00022 define('Auth_OpenID_RP_RETURN_TO_URL_TYPE',
00023 'http://specs.openid.net/auth/2.0/return_to');
00024
00025 function Auth_OpenID_getOpenIDTypeURIs()
00026 {
00027 return array(Auth_OpenID_TYPE_2_0_IDP,
00028 Auth_OpenID_TYPE_2_0,
00029 Auth_OpenID_TYPE_1_2,
00030 Auth_OpenID_TYPE_1_1,
00031 Auth_OpenID_TYPE_1_0,
00032 Auth_OpenID_RP_RETURN_TO_URL_TYPE);
00033 }
00034
00038 class Auth_OpenID_ServiceEndpoint {
00039 function Auth_OpenID_ServiceEndpoint()
00040 {
00041 $this->claimed_id = null;
00042 $this->server_url = null;
00043 $this->type_uris = array();
00044 $this->local_id = null;
00045 $this->canonicalID = null;
00046 $this->used_yadis = false;
00047 $this->display_identifier = null;
00048 }
00049
00050 function getDisplayIdentifier()
00051 {
00052 if ($this->display_identifier) {
00053 return $this->display_identifier;
00054 }
00055 if (! $this->claimed_id) {
00056 return $this->claimed_id;
00057 }
00058 $parsed = parse_url($this->claimed_id);
00059 $scheme = $parsed['scheme'];
00060 $host = $parsed['host'];
00061 $path = $parsed['path'];
00062 if (array_key_exists('query', $parsed)) {
00063 $query = $parsed['query'];
00064 $no_frag = "$scheme://$host$path?$query";
00065 } else {
00066 $no_frag = "$scheme://$host$path";
00067 }
00068 return $no_frag;
00069 }
00070
00071 function usesExtension($extension_uri)
00072 {
00073 return in_array($extension_uri, $this->type_uris);
00074 }
00075
00076 function preferredNamespace()
00077 {
00078 if (in_array(Auth_OpenID_TYPE_2_0_IDP, $this->type_uris) ||
00079 in_array(Auth_OpenID_TYPE_2_0, $this->type_uris)) {
00080 return Auth_OpenID_OPENID2_NS;
00081 } else {
00082 return Auth_OpenID_OPENID1_NS;
00083 }
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 function matchTypes($type_uris)
00098 {
00099 $result = array();
00100 foreach ($type_uris as $test_uri) {
00101 if ($this->supportsType($test_uri)) {
00102 $result[] = $test_uri;
00103 }
00104 }
00105
00106 return $result;
00107 }
00108
00109 function supportsType($type_uri)
00110 {
00111
00112 return ((in_array($type_uri, $this->type_uris)) ||
00113 (($type_uri == Auth_OpenID_TYPE_2_0) &&
00114 $this->isOPIdentifier()));
00115 }
00116
00117 function compatibilityMode()
00118 {
00119 return $this->preferredNamespace() != Auth_OpenID_OPENID2_NS;
00120 }
00121
00122 function isOPIdentifier()
00123 {
00124 return in_array(Auth_OpenID_TYPE_2_0_IDP, $this->type_uris);
00125 }
00126
00127 function fromOPEndpointURL($op_endpoint_url)
00128 {
00129
00130
00131 $obj = new Auth_OpenID_ServiceEndpoint();
00132 $obj->server_url = $op_endpoint_url;
00133 $obj->type_uris = array(Auth_OpenID_TYPE_2_0_IDP);
00134 return $obj;
00135 }
00136
00137 function parseService($yadis_url, $uri, $type_uris, $service_element)
00138 {
00139
00140
00141
00142 $this->type_uris = $type_uris;
00143 $this->server_url = $uri;
00144 $this->used_yadis = true;
00145
00146 if (!$this->isOPIdentifier()) {
00147 $this->claimed_id = $yadis_url;
00148 $this->local_id = Auth_OpenID_findOPLocalIdentifier(
00149 $service_element,
00150 $this->type_uris);
00151 if ($this->local_id === false) {
00152 return false;
00153 }
00154 }
00155
00156 return true;
00157 }
00158
00159 function getLocalID()
00160 {
00161
00162
00163 if ($this->local_id === null && $this->canonicalID === null) {
00164 return $this->claimed_id;
00165 } else {
00166 if ($this->local_id) {
00167 return $this->local_id;
00168 } else {
00169 return $this->canonicalID;
00170 }
00171 }
00172 }
00173
00174
00175
00176
00177
00178
00179
00180 function fromXRDS($uri, $xrds_text)
00181 {
00182 $xrds =& Auth_Yadis_XRDS::parseXRDS($xrds_text);
00183
00184 if ($xrds) {
00185 $yadis_services =
00186 $xrds->services(array('filter_MatchesAnyOpenIDType'));
00187 return Auth_OpenID_makeOpenIDEndpoints($uri, $yadis_services);
00188 }
00189
00190 return null;
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200 function fromDiscoveryResult($discoveryResult)
00201 {
00202 if ($discoveryResult->isXRDS()) {
00203 return Auth_OpenID_ServiceEndpoint::fromXRDS(
00204 $discoveryResult->normalized_uri,
00205 $discoveryResult->response_text);
00206 } else {
00207 return Auth_OpenID_ServiceEndpoint::fromHTML(
00208 $discoveryResult->normalized_uri,
00209 $discoveryResult->response_text);
00210 }
00211 }
00212
00213 function fromHTML($uri, $html)
00214 {
00215 $discovery_types = array(
00216 array(Auth_OpenID_TYPE_2_0,
00217 'openid2.provider', 'openid2.local_id'),
00218 array(Auth_OpenID_TYPE_1_1,
00219 'openid.server', 'openid.delegate')
00220 );
00221
00222 $services = array();
00223
00224 foreach ($discovery_types as $triple) {
00225 list($type_uri, $server_rel, $delegate_rel) = $triple;
00226
00227 $urls = Auth_OpenID_legacy_discover($html, $server_rel,
00228 $delegate_rel);
00229
00230 if ($urls === false) {
00231 continue;
00232 }
00233
00234 list($delegate_url, $server_url) = $urls;
00235
00236 $service = new Auth_OpenID_ServiceEndpoint();
00237 $service->claimed_id = $uri;
00238 $service->local_id = $delegate_url;
00239 $service->server_url = $server_url;
00240 $service->type_uris = array($type_uri);
00241
00242 $services[] = $service;
00243 }
00244
00245 return $services;
00246 }
00247
00248 function copy()
00249 {
00250 $x = new Auth_OpenID_ServiceEndpoint();
00251
00252 $x->claimed_id = $this->claimed_id;
00253 $x->server_url = $this->server_url;
00254 $x->type_uris = $this->type_uris;
00255 $x->local_id = $this->local_id;
00256 $x->canonicalID = $this->canonicalID;
00257 $x->used_yadis = $this->used_yadis;
00258
00259 return $x;
00260 }
00261 }
00262
00263 function Auth_OpenID_findOPLocalIdentifier($service, $type_uris)
00264 {
00265
00266
00267
00268
00269
00270 $service->parser->registerNamespace('openid',
00271 Auth_OpenID_XMLNS_1_0);
00272
00273 $service->parser->registerNamespace('xrd',
00274 Auth_Yadis_XMLNS_XRD_2_0);
00275
00276 $parser =& $service->parser;
00277
00278 $permitted_tags = array();
00279
00280 if (in_array(Auth_OpenID_TYPE_1_1, $type_uris) ||
00281 in_array(Auth_OpenID_TYPE_1_0, $type_uris)) {
00282 $permitted_tags[] = 'openid:Delegate';
00283 }
00284
00285 if (in_array(Auth_OpenID_TYPE_2_0, $type_uris)) {
00286 $permitted_tags[] = 'xrd:LocalID';
00287 }
00288
00289 $local_id = null;
00290
00291 foreach ($permitted_tags as $tag_name) {
00292 $tags = $service->getElements($tag_name);
00293
00294 foreach ($tags as $tag) {
00295 $content = $parser->content($tag);
00296
00297 if ($local_id === null) {
00298 $local_id = $content;
00299 } else if ($local_id != $content) {
00300 return false;
00301 }
00302 }
00303 }
00304
00305 return $local_id;
00306 }
00307
00308 function filter_MatchesAnyOpenIDType(&$service)
00309 {
00310 $uris = $service->getTypes();
00311
00312 foreach ($uris as $uri) {
00313 if (in_array($uri, Auth_OpenID_getOpenIDTypeURIs())) {
00314 return true;
00315 }
00316 }
00317
00318 return false;
00319 }
00320
00321 function Auth_OpenID_bestMatchingService($service, $preferred_types)
00322 {
00323
00324
00325
00326
00327
00328
00329
00330
00331 foreach ($preferred_types as $index => $typ) {
00332 if (in_array($typ, $service->type_uris)) {
00333 return $index;
00334 }
00335 }
00336
00337 return count($preferred_types);
00338 }
00339
00340 function Auth_OpenID_arrangeByType($service_list, $preferred_types)
00341 {
00342
00343
00344
00345
00346
00347 $prio_services = array();
00348 foreach ($service_list as $index => $service) {
00349 $prio_services[] = array(Auth_OpenID_bestMatchingService($service,
00350 $preferred_types),
00351 $index, $service);
00352 }
00353
00354 sort($prio_services);
00355
00356
00357
00358 foreach ($prio_services as $index => $s) {
00359 $prio_services[$index] = $prio_services[$index][2];
00360 }
00361
00362 return $prio_services;
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372 function Auth_OpenID_getOPOrUserServices($openid_services)
00373 {
00374 $op_services = Auth_OpenID_arrangeByType($openid_services,
00375 array(Auth_OpenID_TYPE_2_0_IDP));
00376
00377 $openid_services = Auth_OpenID_arrangeByType($openid_services,
00378 Auth_OpenID_getOpenIDTypeURIs());
00379
00380 if ($op_services) {
00381 return $op_services;
00382 } else {
00383 return $openid_services;
00384 }
00385 }
00386
00387 function Auth_OpenID_makeOpenIDEndpoints($uri, $yadis_services)
00388 {
00389 $s = array();
00390
00391 if (!$yadis_services) {
00392 return $s;
00393 }
00394
00395 foreach ($yadis_services as $service) {
00396 $type_uris = $service->getTypes();
00397 $uris = $service->getURIs();
00398
00399
00400
00401 if ($type_uris &&
00402 $uris) {
00403 foreach ($uris as $service_uri) {
00404 $openid_endpoint = new Auth_OpenID_ServiceEndpoint();
00405 if ($openid_endpoint->parseService($uri,
00406 $service_uri,
00407 $type_uris,
00408 $service)) {
00409 $s[] = $openid_endpoint;
00410 }
00411 }
00412 }
00413 }
00414
00415 return $s;
00416 }
00417
00418 function Auth_OpenID_discoverWithYadis($uri, &$fetcher,
00419 $endpoint_filter='Auth_OpenID_getOPOrUserServices',
00420 $discover_function=null)
00421 {
00422
00423
00424
00425
00426
00427
00428
00429 if ($discover_function === null) {
00430 $discover_function = array('Auth_Yadis_Yadis', 'discover');
00431 }
00432
00433 $openid_services = array();
00434
00435 $response = call_user_func_array($discover_function,
00436 array($uri, &$fetcher));
00437
00438 $yadis_url = $response->normalized_uri;
00439 $yadis_services = array();
00440
00441 if ($response->isFailure()) {
00442 return array($uri, array());
00443 }
00444
00445 $openid_services = Auth_OpenID_ServiceEndpoint::fromXRDS(
00446 $yadis_url,
00447 $response->response_text);
00448
00449 if (!$openid_services) {
00450 if ($response->isXRDS()) {
00451 return Auth_OpenID_discoverWithoutYadis($uri,
00452 $fetcher);
00453 }
00454
00455
00456
00457 $openid_services = Auth_OpenID_ServiceEndpoint::fromHTML(
00458 $yadis_url,
00459 $response->response_text);
00460 }
00461
00462 $openid_services = call_user_func_array($endpoint_filter,
00463 array(&$openid_services));
00464
00465 return array($yadis_url, $openid_services);
00466 }
00467
00468 function Auth_OpenID_discoverURI($uri, &$fetcher)
00469 {
00470 $uri = Auth_OpenID::normalizeUrl($uri);
00471 return Auth_OpenID_discoverWithYadis($uri, $fetcher);
00472 }
00473
00474 function Auth_OpenID_discoverWithoutYadis($uri, &$fetcher)
00475 {
00476 $http_resp = @$fetcher->get($uri);
00477
00478 if ($http_resp->status != 200 and $http_resp->status != 206) {
00479 return array($uri, array());
00480 }
00481
00482 $identity_url = $http_resp->final_url;
00483
00484
00485
00486 $openid_services = Auth_OpenID_ServiceEndpoint::fromHTML(
00487 $identity_url,
00488 $http_resp->body);
00489
00490 return array($identity_url, $openid_services);
00491 }
00492
00493 function Auth_OpenID_discoverXRI($iname, &$fetcher)
00494 {
00495 $resolver = new Auth_Yadis_ProxyResolver($fetcher);
00496 list($canonicalID, $yadis_services) =
00497 $resolver->query($iname,
00498 Auth_OpenID_getOpenIDTypeURIs(),
00499 array('filter_MatchesAnyOpenIDType'));
00500
00501 $openid_services = Auth_OpenID_makeOpenIDEndpoints($iname,
00502 $yadis_services);
00503
00504 $openid_services = Auth_OpenID_getOPOrUserServices($openid_services);
00505
00506 for ($i = 0; $i < count($openid_services); $i++) {
00507 $openid_services[$i]->canonicalID = $canonicalID;
00508 $openid_services[$i]->claimed_id = $canonicalID;
00509 $openid_services[$i]->display_identifier = $iname;
00510 }
00511
00512
00513 return array($iname, $openid_services);
00514 }
00515
00516 function Auth_OpenID_discover($uri, &$fetcher)
00517 {
00518
00519
00520 if ($fetcher->isHTTPS($uri) && !$fetcher->supportsSSL()) {
00521 return array($uri, array());
00522 }
00523
00524 if (Auth_Yadis_identifierScheme($uri) == 'XRI') {
00525 $result = Auth_OpenID_discoverXRI($uri, $fetcher);
00526 } else {
00527 $result = Auth_OpenID_discoverURI($uri, $fetcher);
00528 }
00529
00530
00531
00532 if (!$fetcher->supportsSSL()) {
00533 $http_endpoints = array();
00534 list($new_uri, $endpoints) = $result;
00535
00536 foreach ($endpoints as $e) {
00537 if (!$fetcher->isHTTPS($e->server_url)) {
00538 $http_endpoints[] = $e;
00539 }
00540 }
00541
00542 $result = array($new_uri, $http_endpoints);
00543 }
00544
00545 return $result;
00546 }
00547
00548 ?>