├── .gitignore ├── admin ├── library-name ├── darcs-ignore ├── checkimport ├── checkimports ├── syntaxcheck ├── nobadbraces ├── findglobals ├── findallphp ├── findphp ├── otb_test.php ├── webtest.php ├── nobadcase ├── prepare-release ├── docblocks ├── fixperms ├── open_tag ├── nolonglines ├── mathlib ├── makedoc.sh ├── notabs ├── docblocks.pl ├── package.xml ├── adminutil.php ├── longlines.pl ├── gettlds.py ├── runtests ├── xmlconfig.py ├── package2.xml ├── tutorials │ └── OpenID │ │ └── OpenID.pkg ├── brace_style.pl ├── phpaliases.py └── packagexml.py ├── examples ├── server │ ├── index.php │ ├── lib │ │ ├── render │ │ │ ├── idpXrds.php │ │ │ ├── idpage.php │ │ │ ├── userXrds.php │ │ │ ├── about.php │ │ │ ├── trust.php │ │ │ └── login.php │ │ ├── common.php │ │ ├── render.php │ │ ├── session.php │ │ └── actions.php │ ├── server.php │ └── openid-server.css ├── consumer │ ├── index.php │ ├── try_auth.php │ ├── common.php │ └── finish_auth.php ├── discover.php └── README.md ├── Tests ├── Auth │ ├── Yadis │ │ ├── data │ │ │ ├── not-xrds.xml │ │ │ ├── no-xrd.xml │ │ │ ├── example-xrds.xml │ │ │ ├── brian.multi_uri.xrds │ │ │ ├── brian.xrds │ │ │ ├── uri_priority.xrds │ │ │ ├── README │ │ │ ├── pip.xrds │ │ │ ├── brian_priority.xrds │ │ │ ├── spoof1.xrds │ │ │ ├── spoof2.xrds │ │ │ ├── brian.multi.xrds │ │ │ ├── spoof3.xrds │ │ │ ├── test1-xrd.xml │ │ │ ├── delegated-20060809.xrds │ │ │ ├── delegated-20060809-r1.xrds │ │ │ ├── delegated-20060809-r2.xrds │ │ │ ├── prefixsometimes.xrds │ │ │ ├── sometimesprefix.xrds │ │ │ ├── subsegments.xrds │ │ │ ├── test1-discover.txt │ │ │ ├── accept.txt │ │ │ ├── test1-parsehtml.txt │ │ │ └── ref.xrds │ │ ├── TestUtil.php │ │ ├── ParseHTML.php │ │ ├── Yadis.php │ │ └── DiscoverData.php │ └── OpenID │ │ ├── data │ │ ├── test_discover_yadis_no_delegate.xml │ │ ├── test_discover_openid_no_delegate.html │ │ ├── test_discover_openid2_xrds_no_local_id.xml │ │ ├── test_discover_yadis_0entries.xml │ │ ├── openid.html │ │ ├── test_discover_yadis_idp.xml │ │ ├── test_discover_openid2_xrds.xml │ │ ├── test_discover_openid.html │ │ ├── test_discover_openid2.html │ │ ├── test_discover_openid_1_and_2.html │ │ ├── test_discover_yadis_idp_delegate.xml │ │ ├── test_discover_yadis_another_delegate.xml │ │ ├── test_discover_openid_and_yadis.html │ │ ├── test_discover_yadis_2_bad_local_id.xml │ │ ├── test_discover_openid_1_and_2_xrds.xml │ │ ├── test_discover_openid_1_and_2_xrds_bad_delegate.xml │ │ ├── test_discover_openid_ssl.xml │ │ ├── test_discover_yadis_2entries_idp.xml │ │ ├── test_discover_yadis_2entries_delegate.xml │ │ ├── urinorm.txt │ │ ├── hmac-sha256.txt │ │ └── hmac-sha1.txt │ │ ├── Extension.php │ │ ├── CryptUtil.php │ │ ├── Association.php │ │ ├── TestUtil.php │ │ ├── URINorm.php │ │ ├── MemStore.php │ │ └── Nonce.php └── TestDriver.php ├── contrib └── google │ └── php-openid-apps-discover-1.0.1.tar.gz ├── README.Debian ├── README.git ├── composer.json ├── Auth ├── OpenID │ ├── ServerRequest.php │ ├── Extension.php │ ├── MySQLStore.php │ ├── SQLiteStore.php │ ├── KVForm.php │ ├── Nonce.php │ ├── HMAC.php │ ├── DiffieHellman.php │ ├── DumbStore.php │ ├── CryptUtil.php │ ├── PostgreSQLStore.php │ └── DatabaseConnection.php └── Yadis │ ├── Misc.php │ └── XRIRes.php ├── CHANGES-2.1.0 ├── NEWS.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | -------------------------------------------------------------------------------- /admin/library-name: -------------------------------------------------------------------------------- 1 | php-openid -------------------------------------------------------------------------------- /admin/darcs-ignore: -------------------------------------------------------------------------------- 1 | ~$ 2 | ^doc(/|$) 3 | ^CHANGELOG$ 4 | -------------------------------------------------------------------------------- /admin/checkimport: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | -------------------------------------------------------------------------------- /examples/server/index.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Tests/Auth/Yadis/data/not-xrds.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /admin/checkimports: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ./admin/findphp | xargs -L 1 ./admin/checkimport -------------------------------------------------------------------------------- /admin/syntaxcheck: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | for file in `./admin/findallphp` 4 | do php -l $file 5 | done 6 | -------------------------------------------------------------------------------- /admin/nobadbraces: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | ./admin/findphp | xargs -L 1 /usr/bin/env perl admin/brace_style.pl 5 | -------------------------------------------------------------------------------- /contrib/google/php-openid-apps-discover-1.0.1.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openid/php-openid/HEAD/contrib/google/php-openid-apps-discover-1.0.1.tar.gz -------------------------------------------------------------------------------- /admin/findglobals: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Find all PHP modules that are likely to have global variables 3 | set -e 4 | 5 | ./admin/findphp | xargs grep '^\$' 6 | -------------------------------------------------------------------------------- /admin/findallphp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | find Auth Tests \ 4 | -name _darcs -prune -o \ 5 | \( -type f \ 6 | -a -name \*.php \ 7 | -a ! -name .\* \ 8 | \) 9 | -------------------------------------------------------------------------------- /admin/findphp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | find Auth Tests \ 4 | -name _darcs -prune -o \ 5 | \( -type f \ 6 | -a -name \*.php \ 7 | -a ! -name .\* \ 8 | \) | grep -v Tests 9 | -------------------------------------------------------------------------------- /admin/otb_test.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README.Debian: -------------------------------------------------------------------------------- 1 | Development Environment Setup 2 | ============================= 3 | 4 | Janrain note: You'll need to run these commands to generate 5 | documentation for this project: 6 | 7 | apt-get install php4-pear 8 | pear install PhpDocumentor 9 | -------------------------------------------------------------------------------- /admin/webtest.php: -------------------------------------------------------------------------------- 1 | addSuites($suites); 10 | $gui->show(); 11 | 12 | ?> 13 | -------------------------------------------------------------------------------- /Tests/Auth/Yadis/data/no-xrd.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /admin/nobadcase: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | bad=$(./admin/findphp | xargs egrep -n "^[^\'\"]*\b(TRUE|FALSE|NULL)\b") 4 | 5 | if [ ! -z "$bad" ] 6 | then 7 | cat <&2 8 | These files contain wrongly capitalized constants: 9 | 10 | $bad 11 | 12 | EOF 13 | exit 1 14 | fi 15 | -------------------------------------------------------------------------------- /admin/prepare-release: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Prepare this repository for release 4 | 5 | REPO_ROOT=$(dirname $(dirname $(readlink --canonicalize "$0"))) 6 | cd "$REPO_ROOT" 7 | 8 | bash ./admin/fixperms 9 | 10 | ./admin/makedoc.sh 11 | 12 | darcs changes --from-tag=. --summary > CHANGELOG 13 | -------------------------------------------------------------------------------- /admin/docblocks: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #set -e 3 | 4 | bad_files=$(./admin/findphp | xargs -L 1 /usr/bin/env perl admin/docblocks.pl) 5 | 6 | if [ "$bad_files" ] 7 | then 8 | cat <&2 9 | These files do not start with docblocks: 10 | 11 | $bad_files 12 | 13 | EOF 14 | exit 1 15 | fi 16 | -------------------------------------------------------------------------------- /README.git: -------------------------------------------------------------------------------- 1 | GitHub is the new home for php-openid library development. 2 | 3 | This library was originally written by JanRain and managed using the darcs RCS. This file is home to notes regarding the migration from darcs to git, and the move from openidenabled.com to github.com. 4 | 5 | Contact: 6 | Brian Ellin 7 | brian@janrain.com 8 | -------------------------------------------------------------------------------- /admin/fixperms: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cat <&2 11 | These PHP files do NOT begin with &2 9 | Found lines > 80 characters in: 10 | 11 | $files_with_long_lines 12 | EOF 13 | exit 1 14 | fi 15 | -------------------------------------------------------------------------------- /admin/mathlib: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | type; 16 | } 17 | 18 | ?> 19 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/data/test_discover_yadis_no_delegate.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | http://openid.net/signon/1.0 8 | http://www.myopenid.com/server 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /admin/makedoc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -v 3 | phpdoc -p on -t doc -d Auth,admin/tutorials -ti "JanRain OpenID Library" \ 4 | --ignore \*~,BigMath.php,Discover.php,CryptUtil.php,DiffieHellman.php,HMACSHA1.php,KVForm.php,Parse.php,TrustRoot.php,HTTPFetcher.php,ParanoidHTTPFetcher.php,PlainHTTPFetcher.php,ParseHTML.php,URINorm.php,XRI.php,XRIRes.php,Misc.php \ 5 | -dn "OpenID" -o "HTML:frames:phphtmllib" 6 | -------------------------------------------------------------------------------- /admin/notabs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Look in the local directory for PHP files that have tabs in them. If 4 | # there are files with tabs, print the list of files and exit with 5 | # non-zero status. 6 | 7 | tabs=$(./admin/findphp | xargs egrep -n ' ' | sort) 8 | 9 | if [ ! -z "$tabs" ] 10 | then 11 | cat <&2 12 | Found tabs in: 13 | $tabs 14 | EOF 15 | exit 1 16 | fi 17 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/data/test_discover_openid_no_delegate.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Identity Page for Smoker 5 | 6 | 7 | 8 |

foo

9 | 10 | 11 | -------------------------------------------------------------------------------- /Tests/Auth/Yadis/data/example-xrds.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | http://example.com/ 10 | http://www.openidenabled.com/ 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/data/test_discover_openid2_xrds_no_local_id.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | http://specs.openid.net/auth/2.0/signon 8 | http://www.myopenid.com/server 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/data/test_discover_yadis_0entries.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | http://is-not-openid.unittest/ 9 | http://noffing.unittest./ 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/data/openid.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Identity Page for Smoker 5 | 6 | 7 | 8 | 9 |

foo

10 | 11 | 12 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/data/test_discover_yadis_idp.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | http://specs.openid.net/auth/2.0/server 9 | http://www.myopenid.com/server 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/data/test_discover_openid2_xrds.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | http://specs.openid.net/auth/2.0/signon 8 | http://www.myopenid.com/server 9 | http://smoker.myopenid.com/ 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/data/test_discover_openid.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Identity Page for Smoker 5 | 6 | 7 | 8 | 9 |

foo

10 | 11 | 12 | -------------------------------------------------------------------------------- /Tests/Auth/Yadis/data/brian.multi_uri.xrds: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | http://openid.net/signon/1.0 10 | http://www.myopenid.com/server 11 | http://example.com/server 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/data/test_discover_openid2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Identity Page for Smoker 5 | 6 | 7 | 8 | 9 |

foo

10 | 11 | 12 | -------------------------------------------------------------------------------- /Tests/Auth/Yadis/data/brian.xrds: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | http://openid.net/signon/1.0 10 | http://www.myopenid.com/server 11 | http://brian.myopenid.com/ 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/data/test_discover_openid_1_and_2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Identity Page for Smoker 5 | 6 | 7 | 8 | 9 |

foo

10 | 11 | 12 | -------------------------------------------------------------------------------- /Tests/Auth/Yadis/data/uri_priority.xrds: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | http://openid.net/signon/1.0 10 | http://no.priority/ 11 | http://one.priority/ 12 | http://zero.priority/ 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/data/test_discover_yadis_idp_delegate.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | http://specs.openid.net/auth/2.0/server 9 | http://www.myopenid.com/server 10 | http://smoker.myopenid.com/ 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/data/test_discover_yadis_another_delegate.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | http://openid.net/signon/1.0 10 | http://vroom.unittest/server 11 | http://smoker.myopenid.com/ 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /admin/docblocks.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl -w 2 | 3 | use strict; 4 | 5 | my $filename = $ARGV[0]; 6 | 7 | if (!$filename) { 8 | print "Usage: docblocks.pl \n"; 9 | exit(1); 10 | } 11 | 12 | my %allowed = ("" => 1, 13 | " 1); 14 | 15 | open(HANDLE, "<", $filename) or die "Cannot open $filename\n"; 16 | 17 | while () { 18 | chomp; 19 | 20 | if ($_ =~ /\/\*\*/) { 21 | exit(0); 22 | } elsif (!$allowed{$_}) { 23 | print $filename."\n"; 24 | exit(1); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/data/test_discover_openid_and_yadis.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Identity Page for Smoker 5 | 6 | 7 | 8 | 9 | 10 |

foo

11 | 12 | 13 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/data/test_discover_yadis_2_bad_local_id.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | http://specs.openid.net/auth/2.0/signon 10 | http://www.myopenid.com/server 11 | http://smoker.myopenid.com/ 12 | http://localid.mismatch.invalid/ 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Tests/Auth/Yadis/data/README: -------------------------------------------------------------------------------- 1 | delegated-20060809.xrds - results from proxy.xri.net, determined by 2 | Drummond and Kevin to be incorrect. 3 | delegated-20060809-r1.xrds - Drummond's 1st correction 4 | delegated-20060809-r2.xrds - Drummond's 2nd correction 5 | 6 | spoofs: keturn's (=!E4)'s attempts to log in with Drummond's i-number (=!D2) 7 | spoof1.xrds 8 | spoof2.xrds 9 | spoof3.xrds - attempt to steal @!C0!D2 by having "at least one" CanonicalID 10 | match the $res service ProviderID. 11 | 12 | ref.xrds - resolving @ootao*test.ref, which refers to a neustar XRI. 13 | -------------------------------------------------------------------------------- /admin/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | %(package_name)s 4 | %(package_summary)s 5 | 6 | %(package_description)s 7 | 8 | %(license_name)s 9 | %(maintainers)s 10 | 11 | %(version)s 12 | %(date)s 13 | %(release_stability)s 14 | 15 | 18 | 19 | %(contents_version_1)s 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/data/test_discover_openid_1_and_2_xrds.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | http://specs.openid.net/auth/2.0/signon 10 | http://openid.net/signon/1.1 11 | http://www.myopenid.com/server 12 | http://smoker.myopenid.com/ 13 | http://smoker.myopenid.com/ 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "openid/php-openid", 3 | "description": "OpenID library for PHP5", 4 | "keywords": ["openid", "authentication", "yadis", "auth"], 5 | "license": "Apache-2.0", 6 | "homepage": "http://github.com/openid/php-openid", 7 | "authors": [ 8 | { 9 | "name": "JanRain Inc.", 10 | "homepage": "http://www.openidenabled.com" 11 | } 12 | ], 13 | "require": { 14 | "php": ">=5.6", 15 | "ext-gmp": "*", 16 | "ext-curl": "*", 17 | "ext-dom": "*" 18 | }, 19 | "autoload": { 20 | "classmap": ["Auth"] 21 | }, 22 | "include-path": ["."] 23 | } 24 | -------------------------------------------------------------------------------- /Tests/Auth/Yadis/data/pip.xrds: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | http://openid.net/signon/1.1 10 | http://openid.net/sreg/1.0 11 | https://pip.verisignlabs.com/server 12 | 13 | 14 | 15 | http://openid.net/signon/1.0 16 | http://openid.net/sreg/1.0 17 | https://pip.verisignlabs.com/server 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/data/test_discover_openid_1_and_2_xrds_bad_delegate.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | http://specs.openid.net/auth/2.0/signon 10 | http://openid.net/signon/1.0 11 | http://openid.net/signon/1.1 12 | http://www.myopenid.com/server 13 | http://smoker.myopenid.com/ 14 | http://localid.mismatch.invalid/ 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Tests/Auth/Yadis/data/brian_priority.xrds: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | http://openid.net/signon/1.0 10 | http://www.schtuff.com/?action=openid_server 11 | http://users.schtuff.com/brian 12 | 13 | 14 | 15 | http://openid.net/signon/1.0 16 | http://www.myopenid.com/server 17 | http://brian.myopenid.com/ 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/data/test_discover_openid_ssl.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | http://openid.net/signon/1.0 10 | http://nossl.vroom.unittest/server 11 | http://smoker.myopenid.com/ 12 | 13 | 14 | http://openid.net/signon/1.0 15 | https://ssl.vroom.unittest/server 16 | http://smoker.myopenid.com/ 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /admin/adminutil.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/data/test_discover_yadis_2entries_idp.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | =!1000 8 | 9 | 10 | http://specs.openid.net/auth/2.0/signon 11 | http://www.myopenid.com/server 12 | http://smoker.myopenid.com/ 13 | 14 | 15 | 16 | http://specs.openid.net/auth/2.0/server 17 | http://www.livejournal.com/openid/server.bml 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /examples/server/lib/render/idpXrds.php: -------------------------------------------------------------------------------- 1 | 9 | 12 | 13 | 14 | %s 15 | %s 16 | 17 | 18 | 19 | '); 20 | 21 | function idpXrds_render() 22 | { 23 | $headers = ['Content-type: application/xrds+xml']; 24 | 25 | $body = sprintf(idp_xrds_pat, 26 | Auth_OpenID_TYPE_2_0_IDP, 27 | buildURL()); 28 | 29 | return [$headers, $body]; 30 | } 31 | 32 | ?> -------------------------------------------------------------------------------- /Tests/Auth/Yadis/TestUtil.php: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 12 | 13 | This is the identity page for users of this server. 14 | 15 | '); 16 | 17 | function idpage_render($identity) 18 | { 19 | $xrdsurl = buildURL('userXrds')."?user=".urlencode($identity); 20 | 21 | $headers = [ 22 | 'X-XRDS-Location: ' . $xrdsurl, 23 | ]; 24 | 25 | 26 | $body = sprintf(idpage_pat, 27 | buildURL(), 28 | $xrdsurl); 29 | return [$headers, $body]; 30 | } 31 | 32 | ?> 33 | -------------------------------------------------------------------------------- /Auth/OpenID/ServerRequest.php: -------------------------------------------------------------------------------- 1 | 13 | * @copyright 2005-2008 Janrain, Inc. 14 | * @license http://www.apache.org/licenses/LICENSE-2.0 Apache 15 | */ 16 | 17 | /** 18 | * Imports 19 | */ 20 | require_once "Auth/OpenID.php"; 21 | 22 | /** 23 | * Object that holds the state of a request to the OpenID server 24 | * 25 | * With accessor functions to get at the internal request data. 26 | * 27 | * @see Auth_OpenID_Server 28 | * @package OpenID 29 | */ 30 | class Auth_OpenID_ServerRequest { 31 | public $mode = null; 32 | } 33 | 34 | -------------------------------------------------------------------------------- /Tests/Auth/Yadis/data/spoof1.xrds: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | *keturn 5 | xri://= 6 | !E4 7 | =!E4 8 | 9 | 10 | xri://$res*auth*($v*2.0) 11 | http://keturn.example.com/resolve/ 12 | =!E4 13 | 14 | 15 | 16 | *isDrummond 17 | =!E4 18 | !D2 19 | =!D2 20 | 21 | http://openid.net/signon/1.0 22 | http://keturn.example.com/openid 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Tests/Auth/Yadis/data/spoof2.xrds: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | *keturn 5 | xri://= 6 | !E4 7 | =!E4 8 | 9 | 10 | xri://$res*auth*($v*2.0) 11 | http://keturn.example.com/resolve/ 12 | xri://= 13 | 14 | 15 | 16 | *isDrummond 17 | xri://= 18 | !D2 19 | =!D2 20 | 21 | http://openid.net/signon/1.0 22 | http://keturn.example.com/openid 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/data/test_discover_yadis_2entries_delegate.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | =!1000 8 | 9 | 10 | http://openid.net/signon/1.0 11 | http://www.myopenid.com/server 12 | http://smoker.myopenid.com/ 13 | 14 | 15 | 16 | http://openid.net/signon/1.0 17 | http://www.livejournal.com/openid/server.bml 18 | http://frank.livejournal.com/ 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /examples/server/lib/render/userXrds.php: -------------------------------------------------------------------------------- 1 | 9 | 12 | 13 | 14 | %s 15 | %s 16 | %s 17 | 18 | 19 | 20 | '); 21 | 22 | function userXrds_render($identity) 23 | { 24 | $headers = ['Content-type: application/xrds+xml']; 25 | 26 | $body = sprintf(user_xrds_pat, 27 | Auth_OpenID_TYPE_2_0, 28 | Auth_OpenID_TYPE_1_1, 29 | buildURL()); 30 | 31 | return [$headers, $body]; 32 | } 33 | 34 | ?> -------------------------------------------------------------------------------- /Tests/Auth/Yadis/data/brian.multi.xrds: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | http://openid.net/signon/1.1 10 | http://www.myopenid.com/server 11 | http://frank.myopenid.com/ 12 | 13 | 14 | 15 | 16 | 17 | 18 | http://bar.com/ 19 | http://bar.com/server 20 | 21 | 22 | 23 | http://foo.com 24 | http://foo.com/server 25 | 26 | 27 | 28 | 29 | 30 | 31 | http://openid.net/signon/1.0 32 | http://www.myopenid.com/server 33 | http://brian.myopenid.com/ 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /examples/server/server.php: -------------------------------------------------------------------------------- 1 | 33 | 34 | 35 | PHP OpenID Server 36 | 37 |

PHP OpenID Server

38 |

39 | This server needs to be configured before it can be used. Edit 40 | config.php to reflect your server's setup, then 41 | load this page again. 42 |

43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Tests/Auth/Yadis/data/spoof3.xrds: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | *keturn 5 | xri://@ 6 | @E4 7 | @!E4 8 | 9 | 10 | xri://$res*auth*($v*2.0) 11 | http://keturn.example.com/resolve/ 12 | @!E4 13 | 14 | 15 | 16 | *is 17 | @!E4 18 | !D2 19 | =!C0 20 | =!E4!01 21 | 22 | xri://$res*auth*($v*2.0) 23 | http://keturn.example.com/resolve/ 24 | @!C0 25 | 26 | 27 | 28 | *drummond 29 | @!C0 30 | !D2 31 | @!C0!D2 32 | 33 | http://openid.net/signon/1.0 34 | http://keturn.example.com/openid 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /admin/longlines.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl -w 2 | 3 | use strict; 4 | 5 | my $filename = $ARGV[0]; 6 | 7 | if (!$filename) { 8 | print "Usage: longlines.pl [length]\n"; 9 | exit(1); 10 | } 11 | 12 | # Set a default maximum line length. 13 | my $max_length = $ARGV[1] || 80; 14 | 15 | my @lines = (); 16 | my $line_num = 0; 17 | 18 | open(HANDLE, "<", $filename) or die "Cannot open $filename\n"; 19 | 20 | # Read the file and track the lines with length > $max_length. 21 | while () { 22 | $line_num++; 23 | # Subtract one because the newline doesn't count toward the 24 | # length. 25 | if (length($_) - 1 > $max_length) { 26 | push @lines, $line_num; 27 | } 28 | } 29 | 30 | # If more than five long lines were found, truncate to five and 31 | # indicate that others were present, too. 32 | if (@lines > 5) { 33 | @lines = @lines[0..4]; 34 | push @lines, "and others"; 35 | } 36 | 37 | # If any long lines were found, notify and exit(1); otherwise, 38 | # exit(0). 39 | if (@lines) { 40 | print $filename." (line".((@lines > 1) ? "s" : "")." ". 41 | join(", ", @lines)." exceed".((@lines == 1) ? "s" : ""). 42 | " length $max_length)\n"; 43 | exit(1); 44 | } else { 45 | exit(0); 46 | } 47 | -------------------------------------------------------------------------------- /admin/gettlds.py: -------------------------------------------------------------------------------- 1 | """ 2 | Fetch the current TLD list from the IANA Web site, parse it, and print 3 | an expression suitable for direct insertion into each library's trust 4 | root validation module 5 | 6 | Usage: 7 | python gettlds.py (php|python|ruby) 8 | 9 | Then cut-n-paste. 10 | """ 11 | 12 | import urllib2 13 | 14 | import sys 15 | 16 | langs = { 17 | 'php': (r"'/\.(", 18 | "'", "|", "|' .", 19 | r")\.?$/'"), 20 | 'python': ("['", 21 | "'", "', '", "',", 22 | "']"), 23 | 'ruby': ("%w'", 24 | "", " ", "", 25 | "'"), 26 | } 27 | 28 | lang = sys.argv[1] 29 | prefix, line_prefix, separator, line_suffix, suffix = langs[lang] 30 | 31 | f = urllib2.urlopen('http://data.iana.org/TLD/tlds-alpha-by-domain.txt') 32 | tlds = [] 33 | output_line = "" 34 | for input_line in f: 35 | if input_line.startswith('#'): 36 | continue 37 | 38 | tld = input_line.strip().lower() 39 | new_output_line = output_line + prefix + tld 40 | if len(new_output_line) > 60: 41 | print output_line + line_suffix 42 | output_line = line_prefix + tld 43 | else: 44 | output_line = new_output_line 45 | prefix = separator 46 | 47 | print output_line + suffix 48 | -------------------------------------------------------------------------------- /examples/server/openid-server.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 0; 3 | margin: 0; 4 | } 5 | 6 | #content { 7 | padding: 0.5em; 8 | max-width: 50em; 9 | } 10 | 11 | ul.error { 12 | background: #ffaaaa; 13 | border: 1px solid #ff0000; 14 | padding: 0.5em; 15 | padding-left: 1.5em; 16 | } 17 | 18 | .login th { 19 | text-align: left; 20 | } 21 | 22 | div.form { 23 | border: thin solid #777777; 24 | background: #dddddd; 25 | padding: 0.5em; 26 | margin-top: 1em; 27 | } 28 | 29 | div.navigation { 30 | border-bottom: thin solid #cccccc; 31 | background: #eeeeee; 32 | font-size: smaller; 33 | padding: 0.5em; 34 | } 35 | 36 | div.navigation h2 { 37 | margin-top: 0; 38 | } 39 | 40 | div.navigation p { 41 | margin: 0; 42 | } 43 | 44 | div.navigation ul { 45 | margin: 0; 46 | } 47 | 48 | div.login p { 49 | margin-top: 0; 50 | } 51 | 52 | h1 { 53 | margin-top: 0; 54 | } 55 | 56 | pre { 57 | padding: 1em; 58 | border: 1px solid black; 59 | background: #ffeebb; 60 | } 61 | 62 | #checkup { 63 | background: url('http://openid.net/favicon.ico') no-repeat; 64 | padding-left: 16px; 65 | } 66 | 67 | th { 68 | text-align: left; 69 | } 70 | 71 | table { 72 | border-collapse: collapse; 73 | margin-bottom: 1em; 74 | } -------------------------------------------------------------------------------- /Tests/Auth/Yadis/data/test1-xrd.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | http://openid.net/signon/1.0 11 | http://www.myopenid.com/server 12 | http://josh.myopenid.com/ 13 | 14 | 15 | 16 | http://lid.netmesh.org/sso/2.0b5 17 | http://lid.netmesh.org/2.0b5 18 | http://mylid.net/josh 19 | 20 | 21 | 22 | http://openid.net/signon/1.0 23 | http://www.livejournal.com/openid/server.bml 24 | http://www.livejournal.com/users/nedthealpaca/ 25 | 26 | 27 | 28 | http://typekey.com/services/1.0 29 | joshhoyt 30 | 31 | 32 | 33 | http://openid.net/signon/1.0 34 | http://www.schtuff.com/openid 35 | http://users.schtuff.com/josh 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Tests/Auth/Yadis/data/delegated-20060809.xrds: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | *ootao 5 | 6 | 2006-08-09T22:07:13.000Z 7 | xri://@ 8 | !5BAD.2AA.3C72.AF46 9 | @!5BAD.2AA.3C72.AF46 10 | 11 | xri://$res*auth*($v*2.0) 12 | 13 | application/xrds+xml;trust=none 14 | http://resolve.ezibroker.net/resolve/@ootao/ 15 | 16 | 17 | http://openid.net/signon/1.0 18 | 19 | https://linksafe.ezibroker.net/server/ 20 | 21 | 22 | 23 | *test1 24 | SUCCESS 25 | xri://!!1003 26 | !0000.0000.3B9A.CA01 27 | @!5BAD.2AA.3C72.AF46!0000.0000.3B9A.CA01 28 | 29 | http://openid.net/signon/1.0 30 | 31 | https://linksafe.ezibroker.net/server/ 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /Tests/Auth/Yadis/data/delegated-20060809-r1.xrds: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | *ootao 5 | 6 | 2006-08-09T22:07:13.000Z 7 | xri://@ 8 | !5BAD.2AA.3C72.AF46 9 | @!5BAD.2AA.3C72.AF46 10 | 11 | xri://$res*auth*($v*2.0) 12 | xri://!!1003 13 | application/xrds+xml;trust=none 14 | http://resolve.ezibroker.net/resolve/@ootao/ 15 | 16 | 17 | http://openid.net/signon/1.0 18 | 19 | https://linksafe.ezibroker.net/server/ 20 | 21 | 22 | 23 | *test1 24 | SUCCESS 25 | xri://!!1003 26 | !0000.0000.3B9A.CA01 27 | @!5BAD.2AA.3C72.AF46!0000.0000.3B9A.CA01 28 | 29 | http://openid.net/signon/1.0 30 | 31 | https://linksafe.ezibroker.net/server/ 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /Tests/Auth/Yadis/data/delegated-20060809-r2.xrds: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | *ootao 5 | 6 | 2006-08-09T22:07:13.000Z 7 | xri://@ 8 | !5BAD.2AA.3C72.AF46 9 | @!5BAD.2AA.3C72.AF46 10 | 11 | xri://$res*auth*($v*2.0) 12 | xri://@!5BAD.2AA.3C72.AF46 13 | application/xrds+xml;trust=none 14 | http://resolve.ezibroker.net/resolve/@ootao/ 15 | 16 | 17 | http://openid.net/signon/1.0 18 | 19 | https://linksafe.ezibroker.net/server/ 20 | 21 | 22 | 23 | *test1 24 | SUCCESS 25 | xri://@!5BAD.2AA.3C72.AF46 26 | !0000.0000.3B9A.CA01 27 | @!5BAD.2AA.3C72.AF46!0000.0000.3B9A.CA01 28 | 29 | http://openid.net/signon/1.0 30 | 31 | https://linksafe.ezibroker.net/server/ 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /Tests/Auth/Yadis/data/prefixsometimes.xrds: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | *ootao 5 | 6 | 2006-08-09T22:07:13.000Z 7 | xri://@ 8 | !5BAD.2AA.3C72.AF46 9 | @!5BAD.2AA.3C72.AF46 10 | 11 | xri://$res*auth*($v*2.0) 12 | xri://@!5BAD.2AA.3C72.AF46 13 | application/xrds+xml;trust=none 14 | http://resolve.ezibroker.net/resolve/@ootao/ 15 | 16 | 17 | http://openid.net/signon/1.0 18 | 19 | https://linksafe.ezibroker.net/server/ 20 | 21 | 22 | 23 | *test1 24 | SUCCESS 25 | xri://@!5BAD.2AA.3C72.AF46 26 | !0000.0000.3B9A.CA01 27 | xri://@!5BAD.2AA.3C72.AF46!0000.0000.3B9A.CA01 28 | 29 | http://openid.net/signon/1.0 30 | 31 | https://linksafe.ezibroker.net/server/ 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /Tests/Auth/Yadis/data/sometimesprefix.xrds: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | *ootao 5 | 6 | 2006-08-09T22:07:13.000Z 7 | xri://@ 8 | !5BAD.2AA.3C72.AF46 9 | xri://@!5BAD.2AA.3C72.AF46 10 | 11 | xri://$res*auth*($v*2.0) 12 | xri://@!5BAD.2AA.3C72.AF46 13 | application/xrds+xml;trust=none 14 | http://resolve.ezibroker.net/resolve/@ootao/ 15 | 16 | 17 | http://openid.net/signon/1.0 18 | 19 | https://linksafe.ezibroker.net/server/ 20 | 21 | 22 | 23 | *test1 24 | SUCCESS 25 | xri://@!5BAD.2AA.3C72.AF46 26 | !0000.0000.3B9A.CA01 27 | @!5BAD.2AA.3C72.AF46!0000.0000.3B9A.CA01 28 | 29 | http://openid.net/signon/1.0 30 | 31 | https://linksafe.ezibroker.net/server/ 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /Auth/Yadis/Misc.php: -------------------------------------------------------------------------------- 1 | 8 | * @copyright 2005-2008 Janrain, Inc. 9 | * @license http://www.apache.org/licenses/LICENSE-2.0 Apache 10 | */ 11 | 12 | function Auth_Yadis_getUCSChars() 13 | { 14 | return [ 15 | [0xA0, 0xD7FF], 16 | [0xF900, 0xFDCF], 17 | [0xFDF0, 0xFFEF], 18 | [0x10000, 0x1FFFD], 19 | [0x20000, 0x2FFFD], 20 | [0x30000, 0x3FFFD], 21 | [0x40000, 0x4FFFD], 22 | [0x50000, 0x5FFFD], 23 | [0x60000, 0x6FFFD], 24 | [0x70000, 0x7FFFD], 25 | [0x80000, 0x8FFFD], 26 | [0x90000, 0x9FFFD], 27 | [0xA0000, 0xAFFFD], 28 | [0xB0000, 0xBFFFD], 29 | [0xC0000, 0xCFFFD], 30 | [0xD0000, 0xDFFFD], 31 | [0xE1000, 0xEFFFD], 32 | ]; 33 | } 34 | 35 | function Auth_Yadis_getIPrivateChars() 36 | { 37 | return [ 38 | [0xE000, 0xF8FF], 39 | [0xF0000, 0xFFFFD], 40 | [0x100000, 0x10FFFD], 41 | ]; 42 | } 43 | 44 | function Auth_Yadis_pct_escape_unicode($char_match) 45 | { 46 | $c = $char_match[0]; 47 | $result = ""; 48 | for ($i = 0; $i < strlen($c); $i++) { 49 | $result .= "%" . sprintf("%X", ord($c[$i])); 50 | } 51 | return $result; 52 | } 53 | 54 | function Auth_Yadis_startswith($s, $stuff) 55 | { 56 | return strpos($s, $stuff) === 0; 57 | } 58 | 59 | -------------------------------------------------------------------------------- /examples/server/lib/render/about.php: -------------------------------------------------------------------------------- 1 | 8 | An error occurred when processing your request: 9 |
10 | %s 11 | '); 12 | 13 | define('about_body', 14 | '

15 | This is an OpenID server 16 | endpoint. This server is built on the JanRain PHP OpenID 18 | library. Since OpenID consumer sites will need to directly contact this 19 | server, it must be accessible over the Internet (not behind a firewall). 20 |

21 |

22 | To use this server, you will have to set up a URL to use as an identifier. 23 | Insert the following markup into the <head> of the HTML 24 | document at that URL: 25 |

26 |
<link rel="openid.server" href="%s" />
27 |

28 | Then configure this server so that you can log in with that URL. 29 |

30 | '); 31 | 32 | /** 33 | * Render the about page, potentially with an error message 34 | */ 35 | function about_render($error=false, $internal=true) 36 | { 37 | $headers = []; 38 | $body = sprintf(about_body, buildURL()); 39 | if ($error) { 40 | $headers[] = $internal ? http_internal_error : http_bad_request; 41 | $body .= sprintf(about_error_template, htmlspecialchars($error)); 42 | } 43 | $current_user = getLoggedInUser(); 44 | return page_render($body, $current_user, 'OpenID Server Endpoint'); 45 | } 46 | 47 | ?> -------------------------------------------------------------------------------- /admin/runtests: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Get the absolute path containing this script 4 | cd $(dirname "$0") 5 | HERE=$PWD 6 | 7 | test_import () { 8 | ./admin/checkimports 9 | } 10 | 11 | test_syntax () { 12 | ./admin/syntaxcheck 13 | } 14 | 15 | test_tabs () { 16 | /usr/bin/env bash "$HERE/notabs" 17 | } 18 | 19 | test_longlines () { 20 | /usr/bin/env bash "$HERE/nolonglines" 21 | } 22 | 23 | test_nobadbraces () { 24 | /usr/bin/env bash "$HERE/nobadbraces" 25 | } 26 | 27 | test_nobadcase () { 28 | /usr/bin/env bash "$HERE/nobadcase" 29 | } 30 | 31 | test_opentag () { 32 | /usr/bin/env bash "$HERE/open_tag" 33 | } 34 | 35 | test_docblocks () { 36 | /usr/bin/env bash "$HERE/docblocks" 37 | } 38 | 39 | test_php () { 40 | if uname -a | grep -i cygwin >/dev/null 2>/dev/null ; then 41 | /usr/bin/env php "$(dirname "$0")/texttest.php" --insecure-rand \ 42 | $TEXTTEST_ARGS 43 | else 44 | /usr/bin/env php "$HERE/texttest.php" $TEXTTEST_ARGS 45 | fi 46 | } 47 | 48 | tests="syntax tabs longlines nobadbraces nobadcase opentag docblocks php import" 49 | 50 | failures= 51 | 52 | # Run in repository root (parent of this directory) 53 | cd $(dirname "$HERE") 54 | 55 | chmod +x ./admin/fixperms 56 | ./admin/fixperms 57 | 58 | for test_name in $tests 59 | do 60 | echo "Running test $test_name" 1>&2 61 | if ! eval "test_$test_name" 62 | then 63 | failures="$failures $test_name" 64 | fi 65 | done 66 | 67 | if [ ! -z "$failures" ] 68 | then 69 | echo "Failures in: $failures" 1>&2 70 | exit 1 71 | fi 72 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/Extension.php: -------------------------------------------------------------------------------- 1 | toMessage($oid1_msg); 22 | $namespaces = $oid1_msg->namespaces; 23 | 24 | $this->assertTrue($namespaces->isImplicit($ext->ns_uri)); 25 | $this->assertEquals($ext->ns_uri, 26 | $namespaces->getNamespaceURI($ext->ns_alias)); 27 | $this->assertEquals($ext->ns_alias, 28 | $namespaces->getAlias($ext->ns_uri)); 29 | } 30 | 31 | function test_OpenID2() 32 | { 33 | $oid2_msg = new Auth_OpenID_Message(Auth_OpenID_OPENID2_NS); 34 | $ext = new _ExtensionTest_DummyExtension(); 35 | $ext->toMessage($oid2_msg); 36 | $namespaces = $oid2_msg->namespaces; 37 | $this->assertFalse($namespaces->isImplicit($ext->ns_uri)); 38 | $this->assertEquals($ext->ns_uri, 39 | $namespaces->getNamespaceURI($ext->ns_alias)); 40 | $this->assertEquals($ext->ns_alias, 41 | $namespaces->getAlias($ext->ns_uri)); 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /examples/server/lib/render/trust.php: -------------------------------------------------------------------------------- 1 | 8 |
9 | %s 10 | 11 | 12 |
13 | 14 | '); 15 | 16 | define('normal_pat', 17 | '

Do you wish to confirm your identity ' . 18 | '(%s) with %s?

'); 19 | 20 | define('id_select_pat', 21 | '

You entered the server URL at the RP. 22 | Please choose the name you wish to use. If you enter nothing, the request will be cancelled.
23 |

24 | '); 25 | 26 | define('no_id_pat', 27 | ' 28 | You did not send an identifier with the request, 29 | and it was not an identifier selection request. 30 | Please return to the relying party and try again. 31 | '); 32 | 33 | function trust_render($info) 34 | { 35 | $current_user = getLoggedInUser(); 36 | $lnk = link_render(idURL($current_user)); 37 | $trust_root = htmlspecialchars($info->trust_root); 38 | $trust_url = buildURL('trust', true); 39 | 40 | if ($info->idSelect()) { 41 | $prompt = id_select_pat; 42 | } else { 43 | $prompt = sprintf(normal_pat, $lnk, $trust_root); 44 | } 45 | 46 | $form = sprintf(trust_form_pat, $trust_url, $prompt); 47 | 48 | return page_render($form, $current_user, 'Trust This Site'); 49 | } 50 | 51 | function noIdentifier_render() 52 | { 53 | return page_render(no_id_pat, null, 'No Identifier Sent'); 54 | } 55 | 56 | ?> -------------------------------------------------------------------------------- /Tests/Auth/OpenID/CryptUtil.php: -------------------------------------------------------------------------------- 1 | 12 | * @copyright 2005-2008 Janrain, Inc. 13 | * @license http://www.apache.org/licenses/LICENSE-2.0 Apache 14 | */ 15 | 16 | require_once 'Auth/OpenID.php'; 17 | require_once 'Auth/OpenID/CryptUtil.php'; 18 | 19 | class Tests_Auth_OpenID_CryptUtil extends PHPUnit_Framework_TestCase { 20 | function test_length() 21 | { 22 | $cases = [1, 10, 255]; 23 | foreach ($cases as $length) { 24 | $data = Auth_OpenID_CryptUtil::getBytes($length); 25 | $this->assertEquals(Auth_OpenID::bytes($data), $length); 26 | } 27 | } 28 | 29 | function test_different() 30 | { 31 | $num_iterations = 100; 32 | $data_length = 20; 33 | 34 | $data = Auth_OpenID_CryptUtil::getBytes($num_iterations); 35 | for ($i = 0; $i < $num_iterations; $i++) { 36 | $last = $data; 37 | $data = Auth_OpenID_CryptUtil::getBytes($data_length); 38 | $this->assertFalse($data == $last); 39 | } 40 | } 41 | 42 | function test_cryptrand() 43 | { 44 | // It's possible, but HIGHLY unlikely that a correct 45 | // implementation will fail by returning the same number twice 46 | 47 | $s = Auth_OpenID_CryptUtil::getBytes(32); 48 | $t = Auth_OpenID_CryptUtil::getBytes(32); 49 | $this->assertEquals(Auth_OpenID::bytes($s), 32); 50 | $this->assertEquals(Auth_OpenID::bytes($t), 32); 51 | $this->assertFalse($s == $t); 52 | } 53 | } 54 | 55 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/Association.php: -------------------------------------------------------------------------------- 1 | 12 | * @copyright 2005-2008 Janrain, Inc. 13 | * @license http://www.apache.org/licenses/LICENSE-2.0 Apache 14 | */ 15 | 16 | require_once 'Auth/OpenID/Association.php'; 17 | 18 | class Tests_Auth_OpenID_Association extends PHPUnit_Framework_TestCase { 19 | function test_me() 20 | { 21 | $issued = time(); 22 | $lifetime = 600; 23 | $assoc = new Auth_OpenID_Association('handle', 'secret', $issued, 24 | $lifetime, 'HMAC-SHA1'); 25 | $s = $assoc->serialize(); 26 | $assoc2 = Auth_OpenID_Association::deserialize( 27 | 'Auth_OpenID_Association', $s); 28 | 29 | if ($assoc2 === null) { 30 | $this->fail('deserialize returned null'); 31 | } else { 32 | $this->assertTrue($assoc2->equal($assoc)); 33 | } 34 | } 35 | function test_me256() 36 | { 37 | if(!Auth_OpenID_HMACSHA256_SUPPORTED) return; 38 | $issued = time(); 39 | $lifetime = 600; 40 | $assoc = new Auth_OpenID_Association('handle', 'secret', $issued, 41 | $lifetime, 'HMAC-SHA256'); 42 | $s = $assoc->serialize(); 43 | $assoc2 = Auth_OpenID_Association::deserialize( 44 | 'Auth_OpenID_Association', $s); 45 | 46 | if ($assoc2 === null) { 47 | $this->fail('deserialize returned null'); 48 | } else { 49 | $this->assertTrue($assoc2->equal($assoc)); 50 | } 51 | } 52 | } 53 | 54 | 55 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/TestUtil.php: -------------------------------------------------------------------------------- 1 | getArg($ns, $key); 39 | $error_format = 'Wrong value for openid.%s: expected=%s, actual=%s'; 40 | $error_message = sprintf($error_format, 41 | $key, $expected, $actual); 42 | 43 | $this->assertEquals($expected, $actual, $error_message); 44 | } 45 | 46 | function failIfOpenIDKeyExists($msg, $key, $ns=null) 47 | { 48 | if ($ns === null) { 49 | $ns = Auth_OpenID_OPENID_NS; 50 | } 51 | 52 | $actual = $msg->getArg($ns, $key); 53 | $error_message = sprintf('openid.%s unexpectedly present: %s', 54 | $key, $actual); 55 | 56 | $this->assertFalse($msg->hasKey($ns, $key), 57 | $error_message); 58 | } 59 | } 60 | 61 | -------------------------------------------------------------------------------- /examples/server/lib/render/login.php: -------------------------------------------------------------------------------- 1 | 8 |

9 | 10 | Enter your username into this form to log in to this server. It 11 | can be anything; this is just for demonstration purposes. For 12 | example, entering USERNAME will give you the identity URL 13 | 14 |

%s
15 |

16 | 17 |
18 | 19 | 20 | 21 | 23 | 24 | 25 | 29 | 30 |
26 | 27 | 28 |
31 |
32 | 33 | '); 34 | 35 | define('login_needed_pat', 36 | 'You must be logged in as %s to approve this request.'); 37 | 38 | function login_render($errors=null, $input=null, $needed=null) 39 | { 40 | $current_user = getLoggedInUser(); 41 | if ($input === null) { 42 | $input = $current_user; 43 | } 44 | if ($needed) { 45 | $errors[] = sprintf(login_needed_pat, link_render($needed)); 46 | } 47 | 48 | $esc_input = htmlspecialchars($input, ENT_QUOTES); 49 | $login_url = buildURL('login', true); 50 | $body = sprintf(login_form_pat, idURL('USERNAME'), $login_url, $esc_input); 51 | if ($errors) { 52 | $body = loginError_render($errors) . $body; 53 | } 54 | return page_render($body, $current_user, 'Log In', null, true); 55 | } 56 | 57 | function loginError_render($errors) 58 | { 59 | $text = ''; 60 | foreach ($errors as $error) { 61 | $text .= sprintf("
  • %s
  • \n", $error); 62 | } 63 | return sprintf("
      \n%s
    \n", $text); 64 | } 65 | ?> -------------------------------------------------------------------------------- /admin/xmlconfig.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | This is the package.xml data needed for the PHP OpenID PEAR 4 | package.xml file. Use the 'packagexml.py' program to generate a 5 | package.xml file for a release of this library. 6 | """ 7 | 8 | # This is a list of dicts describing the project leads. This will be 9 | # used to generate XML elements. 10 | leads = [ 11 | {'name': 'Jonathan Daugherty', 12 | 'user': 'cygnus', 13 | 'email': 'cygnus@janrain.com', 14 | 'active': 'yes'}, 15 | {'name': 'Josh Hoyt', 16 | 'user': 'jhoyt', 17 | 'email': 'josh@janrain.com', 18 | 'active': 'yes'} 19 | ] 20 | 21 | # The package name. 22 | package_name = 'Auth_OpenID' 23 | 24 | # The package description. 25 | package_description = 'An implementation of the OpenID single sign-on authentication protocol.' 26 | 27 | # Package summary. 28 | package_summary = 'PHP OpenID' 29 | 30 | # License string. 31 | license_name = 'Apache' 32 | 33 | # License URI. 34 | license_uri = 'http://www.apache.org/licenses/LICENSE-2.0' 35 | 36 | # Director(ies) containing package source, relative to the admin/ 37 | # directory. All .php files in these directories will be included in 38 | # the element of the output XML and will be assigned the 39 | # role 'php'. 40 | contents_dirs = ['../Auth',] 41 | 42 | # Director(ies) containing package documentation. All files and 43 | # subdirectories in these directories will be included in the 44 | # element in the output XML and will be assigned the role 45 | # 'doc'. 46 | docs_dirs = ['../doc', '../examples'] 47 | 48 | # The HTTP package base URI. This is the place on the web where the 49 | # PEAR-installable tarballs will live, and this (plus the package 50 | # tarball name) will be the URL that users pass to "pear install". 51 | package_base_uri = 'http://www.openidenabled.com/resources/downloads/php-openid/pear/' 52 | 53 | # The release stability. Maybe this should be a commandline parameter 54 | # since it might differ from release to release. 55 | release_stability = 'stable' 56 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/URINorm.php: -------------------------------------------------------------------------------- 1 | 13 | * @copyright 2005-2008 Janrain, Inc. 14 | * @license http://www.apache.org/licenses/LICENSE-2.0 Apache 15 | */ 16 | 17 | require_once 'Auth/OpenID/URINorm.php'; 18 | require_once 'Tests/Auth/OpenID/TestUtil.php'; 19 | 20 | class Tests_Auth_OpenID_URINorm_TestCase extends PHPUnit_Framework_TestCase { 21 | function __construct( 22 | $name, $uri, $expected) 23 | { 24 | 25 | $this->setName($name); 26 | $this->uri = $uri; 27 | $this->expected = $expected; 28 | } 29 | 30 | function runTest() 31 | { 32 | $actual = Auth_OpenID_urinorm($this->uri); 33 | $this->assertEquals($this->expected, $actual); 34 | } 35 | } 36 | 37 | class Tests_Auth_OpenID_URINorm extends PHPUnit_Framework_TestSuite { 38 | function _readTestCases() 39 | { 40 | $lines = Tests_Auth_OpenID_readlines('urinorm.txt'); 41 | $cases = []; 42 | $case = []; 43 | for ($i = 0; $i < count($lines) && ($i + 3 <= count($lines)); $i += 4) { 44 | $name = trim($lines[$i]); 45 | $uri = trim($lines[$i + 1]); 46 | $expected = trim($lines[$i + 2]); 47 | if ($expected == 'fail') { 48 | $expected = null; 49 | } 50 | $cases[] = [$name, $uri, $expected]; 51 | } 52 | 53 | return $cases; 54 | } 55 | 56 | function __construct($name) 57 | { 58 | $this->setName($name); 59 | $cases = $this->_readTestCases(); 60 | foreach ($cases as $case) { 61 | list($name, $uri, $expected) = $case; 62 | $this->addTest(new Tests_Auth_OpenID_URINorm_TestCase($name, $uri, $expected)); 63 | } 64 | } 65 | } 66 | 67 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/data/urinorm.txt: -------------------------------------------------------------------------------- 1 | Already normal form 2 | http://example.com/ 3 | http://example.com/ 4 | 5 | Add a trailing slash 6 | http://example.com 7 | http://example.com/ 8 | 9 | Remove an empty port segment 10 | http://example.com:/ 11 | http://example.com/ 12 | 13 | Remove a default port segment 14 | http://example.com:80/ 15 | http://example.com/ 16 | 17 | Capitalization in host names 18 | http://wWw.exaMPLE.COm/ 19 | http://www.example.com/ 20 | 21 | Capitalization in scheme names 22 | htTP://example.com/ 23 | http://example.com/ 24 | 25 | Capitalization in percent-escaped reserved characters 26 | http://example.com/foo%2cbar 27 | http://example.com/foo%2Cbar 28 | 29 | Unescape percent-encoded unreserved characters 30 | http://example.com/foo%2Dbar%2dbaz 31 | http://example.com/foo-bar-baz 32 | 33 | remove_dot_segments example 1 34 | http://example.com/a/b/c/./../../g 35 | http://example.com/a/g 36 | 37 | remove_dot_segments example 2 38 | http://example.com/mid/content=5/../6 39 | http://example.com/mid/6 40 | 41 | remove_dot_segments: single-dot 42 | http://example.com/a/./b 43 | http://example.com/a/b 44 | 45 | remove_dot_segments: double-dot 46 | http://example.com/a/../b 47 | http://example.com/b 48 | 49 | remove_dot_segments: leading double-dot 50 | http://example.com/../b 51 | http://example.com/b 52 | 53 | remove_dot_segments: trailing single-dot 54 | http://example.com/a/. 55 | http://example.com/a/ 56 | 57 | remove_dot_segments: trailing double-dot 58 | http://example.com/a/.. 59 | http://example.com/ 60 | 61 | remove_dot_segments: trailing single-dot-slash 62 | http://example.com/a/./ 63 | http://example.com/a/ 64 | 65 | remove_dot_segments: trailing double-dot-slash 66 | http://example.com/a/../ 67 | http://example.com/ 68 | 69 | Test of all kinds of syntax-based normalization 70 | hTTPS://a/./b/../b/%63/%7bfoo%7d 71 | https://a/b/c/%7Bfoo%7D 72 | 73 | Unsupported scheme 74 | ftp://example.com/ 75 | fail 76 | 77 | Non-absolute URI 78 | http:/foo 79 | fail 80 | 81 | Illegal character in URI 82 | http://.com/ 83 | fail 84 | 85 | Non-ascii character in URI 86 | http://foo.com/ 87 | fail -------------------------------------------------------------------------------- /Tests/Auth/OpenID/data/hmac-sha256.txt: -------------------------------------------------------------------------------- 1 | test_case = 1 2 | key = 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b 3 | data = 0x4869205468657265 4 | digest = 0xb0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7 5 | 6 | test_case = 2 7 | key = 0x4a656665 8 | data = 0x7768617420646f2079612077616e7420666f72206e6f7468696e673f 9 | digest = 0x5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843 10 | 11 | test_case = 3 12 | key = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 13 | data = 0xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd 14 | digest = 0x773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe 15 | 16 | test_case = 4 17 | key = 0x0102030405060708090a0b0c0d0e0f10111213141516171819 18 | data = 0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd 19 | digest = 0x82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b 20 | 21 | test_case = 6 22 | key = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 23 | data = 0x54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374 24 | digest = 0x60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54 25 | 26 | test_case = 7 27 | key = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 28 | data = 0x5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e 29 | digest = 0x9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2 30 | -------------------------------------------------------------------------------- /admin/package2.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | %(package_name)s 10 | %(uri)s 11 | %(package_summary)s 12 | 13 | %(package_description)s 14 | 15 | %(leads)s 16 | %(date)s 17 | 18 | %(version)s 19 | %(version)s 20 | 21 | 22 | %(release_stability)s 23 | %(release_stability)s 24 | 25 | %(license_name)s 26 | 27 | 30 | 31 | 32 | %(contents)s 33 | 34 | 35 | 36 | 37 | 4.3.0 38 | 39 | 40 | 1.4.5 41 | 42 | 43 | 44 | 45 | PHPUnit 46 | pear.php.net 47 | 1.1.1 48 | 49 | 50 | PEAR_DB 51 | pear.php.net 52 | 1.80 53 | 54 | 55 | pgsql 56 | 57 | 58 | mysql 59 | 60 | 61 | sqlite 62 | 63 | 64 | bcmath 65 | 66 | 67 | gmp 68 | 69 | 70 | 71 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /Auth/OpenID/Extension.php: -------------------------------------------------------------------------------- 1 | isOpenID1(); 52 | $added = $message->namespaces->addAlias($this->ns_uri, 53 | $this->ns_alias, 54 | $implicit); 55 | 56 | if ($added === null) { 57 | if ($message->namespaces->getAlias($this->ns_uri) != 58 | $this->ns_alias) { 59 | return null; 60 | } 61 | } 62 | 63 | if ($request !== null) { 64 | $message->updateArgs($this->ns_uri, 65 | $this->getExtensionArgs($request)); 66 | } else { 67 | $message->updateArgs($this->ns_uri, 68 | $this->getExtensionArgs()); 69 | } 70 | return $message; 71 | } 72 | } 73 | 74 | -------------------------------------------------------------------------------- /Tests/Auth/OpenID/data/hmac-sha1.txt: -------------------------------------------------------------------------------- 1 | test_case = 1 2 | key = 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b 3 | key_len = 20 4 | data = "Hi There" 5 | data_len = 8 6 | digest = 0xb617318655057264e28bc0b6fb378c8ef146be00 7 | 8 | test_case = 2 9 | key = "Jefe" 10 | key_len = 4 11 | data = "what do ya want for nothing?" 12 | data_len = 28 13 | digest = 0xeffcdf6ae5eb2fa2d27416d5f184df9c259a7c79 14 | 15 | test_case = 3 16 | key = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 17 | key_len = 20 18 | data = 0xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd 19 | data_len = 50 20 | digest = 0x125d7342b9ac11cd91a39af48aa17b4f63f175d3 21 | 22 | test_case = 4 23 | key = 0x0102030405060708090a0b0c0d0e0f10111213141516171819 24 | key_len = 25 25 | data = 0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd 26 | data_len = 50 27 | digest = 0x4c9007f4026250c6bc8414f9bf50c86c2d7235da 28 | 29 | test_case = 5 30 | key = 0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c 31 | key_len = 20 32 | data = "Test With Truncation" 33 | data_len = 20 34 | digest = 0x4c1a03424b55e07fe7f27be1d58bb9324a9a5a04 35 | digest-96 = 0x4c1a03424b55e07fe7f27be1 36 | 37 | test_case = 6 38 | key = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 39 | key_len = 80 40 | data = "Test Using Larger Than Block-Size Key - Hash Key First" 41 | data_len = 54 42 | digest = 0xaa4ae5e15272d00e95705637ce8a3b55ed402112 43 | 44 | test_case = 7 45 | key = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 46 | key_len = 80 47 | data = "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data" 48 | data_len = 73 49 | digest = 0xe8e99d0f45237d786d6bbaa7965c7808bbff1a91 50 | -------------------------------------------------------------------------------- /examples/consumer/index.php: -------------------------------------------------------------------------------- 1 | 6 | 7 | PHP OpenID Authentication Example 8 | 42 | 43 |

    PHP OpenID Authentication Example

    44 |

    45 | This example consumer uses the PHP 47 | OpenID library. It just verifies that the URL that you enter 48 | is your identity URL. 49 |

    50 | 51 | $msg"; } ?> 52 | $error"; } ?> 53 | $success"; } ?> 54 | 55 |
    56 |
    57 | Identity URL: 58 | 59 | 60 | 61 |

    Optionally, request these PAPE policies:

    62 |

    63 | $uri) { 64 | print ""; 65 | print "$uri
    "; 66 | } ?> 67 |

    68 | 69 | 70 |
    71 |
    72 | 73 | 74 | -------------------------------------------------------------------------------- /examples/discover.php: -------------------------------------------------------------------------------- 1 | 21 | 22 | 23 | OpenID discovery 24 | 25 | 26 |

    OpenID discovery tool

    27 |

    28 | Enter an OpenID URL to begin discovery: 29 |

    30 |
    31 | 32 | 33 |
    34 | 42 |

    Discovery Results for

    43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 53 | 54 | 55 | 56 | 59 | 60 | 61 | 62 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 89 | 90 | 94 | 95 |
    Claimed Identifier
    No OpenID services discovered.
    Discovered OpenID services:

    Server URLserver_url) ?>
    Local IDlocal_id) ?>
    78 |

    Service types:

    79 |
      80 | type_uris as $type_uri) { 82 | ?> 83 |
    • 84 | 87 |
    88 |
    96 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /Auth/OpenID/MySQLStore.php: -------------------------------------------------------------------------------- 1 | sql['nonce_table'] = 26 | "CREATE TABLE %s (\n". 27 | " server_url VARCHAR(2047) NOT NULL,\n". 28 | " timestamp INTEGER NOT NULL,\n". 29 | " salt CHAR(40) NOT NULL,\n". 30 | " UNIQUE (server_url(255), timestamp, salt)\n". 31 | ") ENGINE=InnoDB"; 32 | 33 | $this->sql['assoc_table'] = 34 | "CREATE TABLE %s (\n". 35 | " server_url VARCHAR(2047) NOT NULL,\n". 36 | " handle VARCHAR(255) NOT NULL,\n". 37 | " secret BLOB NOT NULL,\n". 38 | " issued INTEGER NOT NULL,\n". 39 | " lifetime INTEGER NOT NULL,\n". 40 | " assoc_type VARCHAR(64) NOT NULL,\n". 41 | " PRIMARY KEY (server_url(255), handle)\n". 42 | ") ENGINE=InnoDB"; 43 | 44 | $this->sql['set_assoc'] = 45 | "REPLACE INTO %s (server_url, handle, secret, issued,\n". 46 | " lifetime, assoc_type) VALUES (?, ?, !, ?, ?, ?)"; 47 | 48 | $this->sql['get_assocs'] = 49 | "SELECT handle, secret, issued, lifetime, assoc_type FROM %s ". 50 | "WHERE server_url = ?"; 51 | 52 | $this->sql['get_assoc'] = 53 | "SELECT handle, secret, issued, lifetime, assoc_type FROM %s ". 54 | "WHERE server_url = ? AND handle = ?"; 55 | 56 | $this->sql['remove_assoc'] = 57 | "DELETE FROM %s WHERE server_url = ? AND handle = ?"; 58 | 59 | $this->sql['add_nonce'] = 60 | "INSERT INTO %s (server_url, timestamp, salt) VALUES (?, ?, ?)"; 61 | 62 | $this->sql['clean_nonce'] = 63 | "DELETE FROM %s WHERE timestamp < ?"; 64 | 65 | $this->sql['clean_assoc'] = 66 | "DELETE FROM %s WHERE issued + lifetime < ?"; 67 | } 68 | 69 | /** 70 | * @access private 71 | */ 72 | function blobEncode($blob) 73 | { 74 | return "0x" . bin2hex($blob); 75 | } 76 | } 77 | 78 | -------------------------------------------------------------------------------- /Auth/Yadis/XRIRes.php: -------------------------------------------------------------------------------- 1 | fetcher = $fetcher; 18 | $this->proxy_url = $proxy_url; 19 | if (!$this->proxy_url) { 20 | $this->proxy_url = Auth_Yadis_getDefaultProxy(); 21 | } 22 | } 23 | 24 | function queryURL($xri, $service_type = null) 25 | { 26 | // trim off the xri:// prefix 27 | $qxri = substr(Auth_Yadis_toURINormal($xri), 6); 28 | $hxri = $this->proxy_url . $qxri; 29 | $args = [ 30 | '_xrd_r' => 'application/xrds+xml', 31 | ]; 32 | 33 | if ($service_type) { 34 | $args['_xrd_t'] = $service_type; 35 | } else { 36 | // Don't perform service endpoint selection. 37 | $args['_xrd_r'] .= ';sep=false'; 38 | } 39 | 40 | $query = Auth_Yadis_XRIAppendArgs($hxri, $args); 41 | return $query; 42 | } 43 | 44 | function query($xri, $service_types, $filters = []) 45 | { 46 | $services = []; 47 | $canonicalID = null; 48 | foreach ($service_types as $service_type) { 49 | $url = $this->queryURL($xri, $service_type); 50 | $response = $this->fetcher->get($url); 51 | if ($response->status != 200 and $response->status != 206) { 52 | continue; 53 | } 54 | $xrds = Auth_Yadis_XRDS::parseXRDS($response->body); 55 | if (!$xrds) { 56 | continue; 57 | } 58 | $canonicalID = Auth_Yadis_getCanonicalID($xri, 59 | $xrds); 60 | 61 | if ($canonicalID === false) { 62 | return null; 63 | } 64 | 65 | $some_services = $xrds->services($filters); 66 | $services = array_merge($services, $some_services); 67 | // TODO: 68 | // * If we do get hits for multiple service_types, we're 69 | // almost certainly going to have duplicated service 70 | // entries and broken priority ordering. 71 | } 72 | return [$canonicalID, $services]; 73 | } 74 | } 75 | 76 | 77 | -------------------------------------------------------------------------------- /admin/tutorials/OpenID/OpenID.pkg: -------------------------------------------------------------------------------- 1 | 2 | 3 | PHP OpenID API 4 | 5 | 6 | 7 | 8 | JanRain, Inc. 9 | 10 | {@link mailto:openid@janrain.com openid@janrain.com} 11 | 12 | 13 | 14 | 15 | 16 | This is a complete implementation of the OpenID authentication 17 | protocol. This package contains: 18 | 19 | 20 | An OpenID server 21 | An OpenID consumer 22 | Stores for MySQL, PostgreSQL, SQLite, and filesystem-based OpenID data storage 23 | PHPUnit unit tests 24 | An example server and consumer 25 | 26 | 27 | 28 | 29 | For Package Users 30 | 31 | 32 | To install this package, copy the Auth/ 33 | directory in this package to a directory in your PHP include path. 34 | Alternatively, modify your PHP include path to include the 35 | directory that contains Auth/. Any 36 | applications that need this package will then be able to use it. 37 | 38 | 39 | 40 | 41 | 42 | For Developers 43 | 44 | 45 | 46 | See the server and consumer examples in the 47 | examples/ directory of the package. For 48 | details on how to run the examples, see 49 | examples/README. If you want to create your 50 | own OpenID data storage class, please see the {@link Auth_OpenID_OpenIDStore} 51 | class. For information on integrating OpenID relying party support into your site, see 52 | the class documentation for {@link Consumer.php}. 53 | 54 | 55 | 56 | 57 | 58 | 59 | References 60 | 61 | 62 | 63 | {@link http://github.com/openid/php-openid PHP OpenID Library} 64 | 65 | 66 | 67 | {@link http://www.janrain.com JanRain, Inc.} 68 | 69 | 70 | 71 | {@link http://openid.net/developers/dev-mailing-lists/ OpenID Development Discussion Lists} 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /Auth/OpenID/SQLiteStore.php: -------------------------------------------------------------------------------- 1 | sql['nonce_table'] = 23 | "CREATE TABLE %s (server_url VARCHAR(2047), timestamp INTEGER, ". 24 | "salt CHAR(40), UNIQUE (server_url, timestamp, salt))"; 25 | 26 | $this->sql['assoc_table'] = 27 | "CREATE TABLE %s (server_url VARCHAR(2047), handle VARCHAR(255), ". 28 | "secret BLOB(128), issued INTEGER, lifetime INTEGER, ". 29 | "assoc_type VARCHAR(64), PRIMARY KEY (server_url, handle))"; 30 | 31 | $this->sql['set_assoc'] = 32 | "INSERT OR REPLACE INTO %s VALUES (?, ?, ?, ?, ?, ?)"; 33 | 34 | $this->sql['get_assocs'] = 35 | "SELECT handle, secret, issued, lifetime, assoc_type FROM %s ". 36 | "WHERE server_url = ?"; 37 | 38 | $this->sql['get_assoc'] = 39 | "SELECT handle, secret, issued, lifetime, assoc_type FROM %s ". 40 | "WHERE server_url = ? AND handle = ?"; 41 | 42 | $this->sql['remove_assoc'] = 43 | "DELETE FROM %s WHERE server_url = ? AND handle = ?"; 44 | 45 | $this->sql['add_nonce'] = 46 | "INSERT INTO %s (server_url, timestamp, salt) VALUES (?, ?, ?)"; 47 | 48 | $this->sql['clean_nonce'] = 49 | "DELETE FROM %s WHERE timestamp < ?"; 50 | 51 | $this->sql['clean_assoc'] = 52 | "DELETE FROM %s WHERE issued + lifetime < ?"; 53 | } 54 | 55 | /** 56 | * @access private 57 | */ 58 | function _add_nonce($server_url, $timestamp, $salt) 59 | { 60 | // PECL SQLite extensions 1.0.3 and older (1.0.3 is the 61 | // current release at the time of this writing) have a broken 62 | // sqlite_escape_string function that breaks when passed the 63 | // empty string. Prefixing all strings with one character 64 | // keeps them unique and avoids this bug. The nonce table is 65 | // write-only, so we don't have to worry about updating other 66 | // functions with this same bad hack. 67 | return parent::_add_nonce('x' . $server_url, $timestamp, $salt); 68 | } 69 | } 70 | 71 | -------------------------------------------------------------------------------- /Tests/Auth/Yadis/ParseHTML.php: -------------------------------------------------------------------------------- 1 | 12 | * @copyright 2005-2008 Janrain, Inc. 13 | * @license http://www.apache.org/licenses/LICENSE-2.0 Apache 14 | */ 15 | 16 | require_once 'Tests/Auth/Yadis/TestUtil.php'; 17 | require_once 'Auth/Yadis/ParseHTML.php'; 18 | 19 | class Tests_Auth_Yadis_ParseTest extends PHPUnit_Framework_TestCase { 20 | function __construct($case) 21 | { 22 | list($result, $comment, $html) = $case; 23 | 24 | $this->result = $result; 25 | $this->comment = $comment; 26 | $this->html_string = $html; 27 | $this->parser = new Auth_Yadis_ParseHTML(); 28 | } 29 | 30 | function getName() 31 | { 32 | return $this->comment; 33 | } 34 | 35 | function runTest() 36 | { 37 | $value = $this->parser->getHTTPEquiv($this->html_string); 38 | 39 | if ($this->result == "EOF") { 40 | $this->assertTrue($value === null); 41 | } else if ($this->result == "None") { 42 | $this->assertTrue($value === null); 43 | } else { 44 | $this->assertEquals($this->result, $value); 45 | } 46 | } 47 | } 48 | 49 | class Tests_Auth_Yadis_ParseHTML extends PHPUnit_Framework_TestSuite { 50 | 51 | function getName() 52 | { 53 | return "Tests_Auth_Yadis_Parse"; 54 | } 55 | 56 | function parseTests($s) 57 | { 58 | $tests = []; 59 | 60 | $cases = preg_split("/\f\n/", $s); 61 | 62 | foreach ($cases as $case) { 63 | // Split the case text on newline, and keep the first two 64 | // lines and re-join the rest (those are the HTML). 65 | $parts = explode("\n", $case); 66 | $result = $parts[0]; 67 | $html_comment = $parts[1]; 68 | $html_string = implode("\n", array_slice($parts, 2)); 69 | $tests[] = [$result, $html_comment, $html_string]; 70 | } 71 | 72 | return $tests; 73 | } 74 | 75 | function __construct() 76 | { 77 | $test_data = Tests_Auth_Yadis_readdata('test1-parsehtml.txt'); 78 | 79 | $test_cases = $this->parseTests($test_data); 80 | 81 | foreach ($test_cases as $case) { 82 | $this->addTest(new Tests_Auth_Yadis_ParseTest($case)); 83 | } 84 | } 85 | } 86 | 87 | -------------------------------------------------------------------------------- /Tests/Auth/Yadis/data/subsegments.xrds: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | *nishitani 5 | 6 | 2007-12-25T11:33:39.000Z 7 | xri://= 8 | !E117.EF2F.454B.C707 9 | =!E117.EF2F.454B.C707 10 | 11 | http://openid.net/signon/1.0 12 | xri://!!1003!103 13 | https://linksafe.ezibroker.net/server/ 14 | 15 | 16 | xri://$res*auth*($v*2.0) 17 | xri://!!1003!103 18 | application/xrds+xml;trust=none 19 | http://resolve.ezibroker.net/resolve/=nishitani/ 20 | 21 | 22 | xri://+i-service*(+forwarding)*($v*1.0) 23 | 24 | xri://!!1003!103 25 | (+index) 26 | 27 | http://linksafe-forward.ezibroker.net/forwarding/ 28 | 29 | 30 | 31 | *masaki 32 | SUCCESS 33 | xri://!!1003 34 | !0000.0000.3B9A.CA01 35 | =!E117.EF2F.454B.C707!0000.0000.3B9A.CA01 36 | 37 | http://openid.net/signon/1.0 38 | xri://!!1003!103 39 | https://linksafe.ezibroker.net/server/ 40 | 41 | 42 | xri://+i-service*(+contact)*($v*1.0) 43 | 44 | xri://!!1003!103 45 | (+contact) 46 | 47 | http://linksafe-contact.ezibroker.net/contact/ 48 | 49 | 50 | xri://+i-service*(+forwarding)*($v*1.0) 51 | 52 | xri://!!1003!103 53 | (+index) 54 | 55 | http://linksafe-forward.ezibroker.net/forwarding/ 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /admin/brace_style.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl -w 2 | 3 | use strict; 4 | 5 | my $filename = $ARGV[0]; 6 | 7 | if (!$filename) { 8 | print "Usage: modified_otb.pl \n"; 9 | exit(1); 10 | } 11 | 12 | my @results = (); 13 | my $line_num = 0; 14 | my ($NONE, $BRACE, $PAREN) = (0, 1, 2); 15 | my $looking_for = $NONE; 16 | my $last_func_name = ""; 17 | 18 | open(HANDLE, "<", $filename) or die "Cannot open $filename\n"; 19 | 20 | # Read the file and track the lines with length > $max_length. 21 | while () { 22 | $line_num++; 23 | # Subtract one because the newline doesn't count toward the 24 | # length. 25 | chomp; 26 | 27 | if (!$looking_for && 28 | ($_ =~ /^\s*function/) && 29 | ($_ =~ /\{/)) { 30 | # Done (bad): we found a function whose opening line ends with 31 | # a brace, which goes against the PEAR coding guidelines. 32 | 33 | ($last_func_name) = $_ =~ /function\s*(.*)\(/; 34 | 35 | push @results, "'$last_func_name' prototype ends with opening ". 36 | "brace, line $line_num"; 37 | } elsif (!$looking_for && 38 | ($_ =~ /^\s*function/) && 39 | ($_ !~ /\)/)) { 40 | ($last_func_name) = $_ =~ /function\s*(.*)\(/; 41 | $looking_for = $PAREN; 42 | } elsif (($looking_for == $PAREN) && 43 | ($_ =~ /\)/) && 44 | ($_ =~ /\{/)) { 45 | # Done (bad): function prototype and brace are on the same 46 | # line. 47 | push @results, "'$last_func_name' prototype ends with with ". 48 | "opening brace, line $line_num"; 49 | $looking_for = $NONE; 50 | } elsif (($looking_for == $PAREN) && 51 | ($_ =~ /\)/) && 52 | ($_ !~ /\{/)) { 53 | $looking_for = $BRACE; 54 | } elsif (!$looking_for && 55 | ($_ =~ /^\s*function/) && 56 | ($_ =~ /\)/) && 57 | ($_ !~ /\{/)) { 58 | ($last_func_name) = $_ =~ /function\s*(.*)\(/; 59 | $looking_for = $BRACE; 60 | } elsif (($looking_for == $BRACE) && 61 | ($_ eq "{")) { 62 | $looking_for = $NONE; 63 | # Done (good): the brace was found on the line after the 64 | # function prototype. 65 | } else { 66 | # We got here because we got a line that we're not interested 67 | # in. 68 | $looking_for = $NONE; 69 | } 70 | } 71 | 72 | # If any long lines were found, notify and exit(1); otherwise, 73 | # exit(0). 74 | if (@results) { 75 | foreach my $result (@results) { 76 | print "$filename: $result\n"; 77 | } 78 | exit(1); 79 | } else { 80 | exit(0); 81 | } 82 | -------------------------------------------------------------------------------- /CHANGES-2.1.0: -------------------------------------------------------------------------------- 1 | * API Changes 2 | * AX::FetchResponse::fromSuccessResponse - return null when AX 3 | response arguments are absent 4 | * Alter AX fromOpenIDRequest() to take Auth_OpenID_AuthRequest 5 | object instead of Auth_OpenID_Message object so that it matches 6 | its counterpart methods in SREG and PAPE extensions. 7 | * PAPE (Provider Authentication Policy Extension) module 8 | * Updated extension for specification draft 2 9 | * Auth_OpenID_PAPE_Request::fromSuccessResponse returns None if 10 | PAPE response arguments were not signed 11 | * Added functions to generate request/response HTML forms with 12 | auto-submission javascript 13 | * Consumer (relying party) API: 14 | Auth_OpenID_AuthRequest::htmlMarkup 15 | * Server API: Auth_OpenID_OpenIDResponse::toHTML 16 | 17 | * New Features 18 | * Added examples/discover.php, an OpenID service discovery tool 19 | * Add optional form_tag_attrs argument to 20 | Auth_OpenID_ServerResponse::toFormMarkup for setting arbitrary 21 | FORM element attributes 22 | * Fetchers now only read/request first megabyte of response 23 | 24 | * Bug Fixes 25 | * NOT NULL constraints were added to SQLStore tables where 26 | appropriate 27 | * Yadis discovery now properly falls back to HTML-based discovery if 28 | it fails to get an XRDS document 29 | * Auth_OpenID_Decoder now behaves correctly when given a protocol 30 | message with an invalid OpenID namespace or a missing OpenID mode 31 | * Auth_OpenID_OpenIDResponse::toFormMarkup: Use return_to from the 32 | request, not the response fields (Not all responses (i.e. cancel, 33 | setup_needed) include a return_to field.) 34 | * normalize return_to URL before performing return_to verification 35 | * Auth_OpenID_Consumer::_verifyDiscoveryResults: fall back to OpenID 36 | 1.0 type if 1.1 endpoint cannot be found 37 | * Auth_Yadis_ParanoidHTTPFetcher now works correctly with both array 38 | and non-array CURL versions 39 | * Clarified licensing language in all source files 40 | * OpenID 1 association requests no longer explicitly set 41 | no-encryption session type 42 | * Auth_OpenID_ServiceEndpoint::getDisplayIdentifier no longer 43 | includes a fragment, if present, in display identifiers 44 | * check_authentication requests: copy entire response, not just 45 | signed fields. Fixes missing namespace in check_authentication 46 | requests 47 | * Yadis discovery now includes application/xhtml+xml and qualities 48 | in the Accept header 49 | * Normalize URLs correctly with URINorm.php 50 | * Auth_OpenID_MySQLStore: Use ENGINE instead of TYPE when creating 51 | tables 52 | -------------------------------------------------------------------------------- /Tests/Auth/Yadis/Yadis.php: -------------------------------------------------------------------------------- 1 | input_url = $input_url; 15 | $this->redir_uri = $redir_uri; 16 | $this->xrds_uri = $xrds_uri; 17 | $this->num = $num; 18 | } 19 | 20 | function getName() 21 | { 22 | return "Yadis discovery test ".$this->num; 23 | } 24 | 25 | function runTest() 26 | { 27 | $fetcher = Auth_Yadis_Yadis::getHTTPFetcher(); 28 | $y = Auth_Yadis_Yadis::discover( 29 | $this->input_url, $fetcher); 30 | $this->assertTrue($y !== null); 31 | 32 | // Compare parts of returned Yadis object to expected URLs. 33 | $this->assertEquals($this->redir_uri, $y->normalized_uri, "tried $this->input_url"); 34 | 35 | if ($this->xrds_uri) { 36 | $this->assertEquals($this->xrds_uri, $y->xrds_uri); 37 | // Compare contents of actual HTTP GET with that of Yadis 38 | // response. 39 | $f = Auth_Yadis_Yadis::getHTTPFetcher(); 40 | $http_response = $f->get($this->xrds_uri); 41 | 42 | $this->assertEquals($http_response->body, $y->response_text); 43 | } else { 44 | $this->assertTrue($y->xrds_uri === null); 45 | } 46 | } 47 | } 48 | 49 | class Tests_Auth_Yadis_Yadis extends PHPUnit_Framework_TestSuite { 50 | 51 | function getName() 52 | { 53 | return "Tests_Auth_Yadis_Yadis"; 54 | } 55 | 56 | function parseTests($data) 57 | { 58 | $cases = explode("\n", $data); 59 | $tests = []; 60 | 61 | foreach ($cases as $line) { 62 | if ($line && ($line[0] != "#")) { 63 | $tests[] = explode("\t", $line, 3); 64 | } 65 | } 66 | 67 | return $tests; 68 | } 69 | 70 | function __construct() 71 | { 72 | $test_data = file_get_contents('http://www.openidenabled.com/resources/yadis-test/discover/manifest.txt'); 73 | 74 | $test_cases = $this->parseTests($test_data); 75 | 76 | $i = 0; 77 | foreach ($test_cases as $case) { 78 | $i++; 79 | list($input, $redir, $xrds) = $case; 80 | $this->addTest(new Tests_Auth_Yadis_DiscoveryTest($input, 81 | $redir, 82 | $xrds, $i)); 83 | } 84 | } 85 | 86 | } 87 | 88 | -------------------------------------------------------------------------------- /Tests/Auth/Yadis/data/test1-discover.txt: -------------------------------------------------------------------------------- 1 | equiv 2 | Status: 200 OK 3 | Content-Type: text/html 4 | 5 | 6 | 7 | 8 | Joe Schmoe's Homepage 9 | 10 | 11 |

    Joe Schmoe's Homepage

    12 |

    Blah blah blah blah blah blah blah

    13 | 14 | 15 | 16 | header 17 | Status: 200 OK 18 | Content-Type: text/html 19 | YADIS_HEADER: URL_BASE/xrds 20 | 21 | 22 | 23 | Joe Schmoe's Homepage 24 | 25 | 26 |

    Joe Schmoe's Homepage

    27 |

    Blah blah blah blah blah blah blah

    28 | 29 | 30 | xrds 31 | Status: 200 OK 32 | Content-Type: application/xrds+xml 33 | 34 | 35 | 36 | xrds_ctparam 37 | Status: 200 OK 38 | Content-Type: application/xrds+xml; charset=UTF8 39 | 40 | 41 | 42 | xrds_ctcase 43 | Status: 200 OK 44 | Content-Type: appliCATION/XRDS+xml 45 | 46 | 47 | 48 | xrds_html 49 | Status: 200 OK 50 | Content-Type: text/html 51 | 52 | 53 | 54 | redir_equiv 55 | Status: 302 Found 56 | Content-Type: text/plain 57 | Location: URL_BASE/equiv 58 | 59 | You are presently being redirected. 60 | 61 | redir_header 62 | Status: 302 Found 63 | Content-Type: text/plain 64 | Location: URL_BASE/header 65 | 66 | You are presently being redirected. 67 | 68 | redir_xrds 69 | Status: 302 Found 70 | Content-Type: application/xrds+xml 71 | Location: URL_BASE/xrds 72 | 73 | 74 | 75 | redir_xrds_html 76 | Status: 302 Found 77 | Content-Type: text/plain 78 | Location: URL_BASE/xrds_html 79 | 80 | You are presently being redirected. 81 | 82 | redir_redir_equiv 83 | Status: 302 Found 84 | Content-Type: text/plain 85 | Location: URL_BASE/redir_equiv 86 | 87 | You are presently being redirected. 88 | 89 | lowercase_header 90 | Status: 200 OK 91 | Content-Type: text/html 92 | x-xrds-location: URL_BASE/xrds 93 | 94 | 95 | 96 | Joe Schmoe's Homepage 97 | 98 | 99 |

    Joe Schmoe's Homepage

    100 |

    Blah blah blah blah blah blah blah

    101 | 102 | 103 | 404_server_response 104 | Status: 404 Not Found 105 | 106 | EEk! 107 | 108 | 500_server_response 109 | Status: 500 Server error 110 | 111 | EEk! 112 | 113 | 201_server_response 114 | Status: 201 Created 115 | 116 | EEk! 117 | 118 | 404_with_header 119 | Status: 404 Not Found 120 | YADIS_HEADER: URL_BASE/xrds 121 | 122 | EEk! 123 | 124 | 404_with_meta 125 | Status: 404 Not Found 126 | Content-Type: text/html 127 | 128 | 129 | 130 | 131 | Joe Schmoe's Homepage 132 | 133 | 134 |

    Joe Schmoe's Homepage

    135 |

    Blah blah blah blah blah blah blah

    136 | 137 | 138 | -------------------------------------------------------------------------------- /examples/server/lib/common.php: -------------------------------------------------------------------------------- 1 | getCancelURL(); 18 | } else { 19 | $url = getServerURL(); 20 | } 21 | return redirect_render($url); 22 | } 23 | 24 | function doAuth($info, $trusted=null, $fail_cancels=false, 25 | $idpSelect=null) 26 | { 27 | if (!$info) { 28 | // There is no authentication information, so bail 29 | return authCancel(null); 30 | } 31 | 32 | if ($info->idSelect()) { 33 | if ($idpSelect) { 34 | $req_url = idURL($idpSelect); 35 | } else { 36 | $trusted = false; 37 | } 38 | } else { 39 | $req_url = $info->identity; 40 | } 41 | 42 | $user = getLoggedInUser(); 43 | setRequestInfo($info); 44 | 45 | if ((!$info->idSelect()) && ($req_url != idURL($user))) { 46 | return login_render([], $req_url, $req_url); 47 | } 48 | 49 | $trust_root = $info->trust_root; 50 | 51 | if ($trusted) { 52 | setRequestInfo(); 53 | $server = getServer(); 54 | $response = $info->answer(true, null, $req_url); 55 | 56 | // Answer with some sample Simple Registration data. 57 | $sreg_data = [ 58 | 'fullname' => 'Example User', 59 | 'nickname' => 'example', 60 | 'dob' => '1970-01-01', 61 | 'email' => 'invalid@example.com', 62 | 'gender' => 'F', 63 | 'postcode' => '12345', 64 | 'country' => 'ES', 65 | 'language' => 'eu', 66 | 'timezone' => 'America/New_York', 67 | ]; 68 | 69 | // Add the simple registration response values to the OpenID 70 | // response message. 71 | $sreg_request = Auth_OpenID_SRegRequest::fromOpenIDRequest( 72 | $info); 73 | 74 | $sreg_response = Auth_OpenID_SRegResponse::extractResponse( 75 | $sreg_request, $sreg_data); 76 | 77 | $sreg_response->toMessage($response->fields); 78 | 79 | // Generate a response to send to the user agent. 80 | $webresponse = $server->encodeResponse($response); 81 | 82 | $new_headers = []; 83 | 84 | foreach ($webresponse->headers as $k => $v) { 85 | $new_headers[] = $k.": ".$v; 86 | } 87 | 88 | return [$new_headers, $webresponse->body]; 89 | } elseif ($fail_cancels) { 90 | return authCancel($info); 91 | } else { 92 | return trust_render($info); 93 | } 94 | } 95 | 96 | ?> -------------------------------------------------------------------------------- /examples/consumer/try_auth.php: -------------------------------------------------------------------------------- 1 | begin($openid); 24 | 25 | // No auth request means we can't begin OpenID. 26 | if (!$auth_request) { 27 | displayError("Authentication error; not a valid OpenID."); 28 | } 29 | 30 | $sreg_request = Auth_OpenID_SRegRequest::build( 31 | // Required 32 | ['nickname'], 33 | // Optional 34 | ['fullname', 'email']); 35 | 36 | if ($sreg_request) { 37 | $auth_request->addExtension($sreg_request); 38 | } 39 | 40 | $policy_uris = null; 41 | if (isset($_GET['policies'])) { 42 | $policy_uris = $_GET['policies']; 43 | } 44 | 45 | $pape_request = new Auth_OpenID_PAPE_Request($policy_uris); 46 | if ($pape_request) { 47 | $auth_request->addExtension($pape_request); 48 | } 49 | 50 | // Redirect the user to the OpenID server for authentication. 51 | // Store the token for this authentication so we can verify the 52 | // response. 53 | 54 | // For OpenID 1, send a redirect. For OpenID 2, use a Javascript 55 | // form to send a POST request to the server. 56 | if ($auth_request->shouldSendRedirect()) { 57 | $redirect_url = $auth_request->redirectURL(getTrustRoot(), 58 | getReturnTo()); 59 | 60 | // If the redirect URL can't be built, display an error 61 | // message. 62 | if (Auth_OpenID::isFailure($redirect_url)) { 63 | displayError("Could not redirect to server: " . $redirect_url->message); 64 | } else { 65 | // Send redirect. 66 | header("Location: ".$redirect_url); 67 | } 68 | } else { 69 | // Generate form markup and render it. 70 | $form_id = 'openid_message'; 71 | $form_html = $auth_request->htmlMarkup(getTrustRoot(), getReturnTo(), 72 | false, ['id' => $form_id]); 73 | 74 | // Display an error if the form markup couldn't be generated; 75 | // otherwise, render the HTML. 76 | if (Auth_OpenID::isFailure($form_html)) { 77 | displayError("Could not redirect to server: " . $form_html->message); 78 | } else { 79 | print $form_html; 80 | } 81 | } 82 | } 83 | 84 | run(); 85 | 86 | ?> -------------------------------------------------------------------------------- /Auth/OpenID/KVForm.php: -------------------------------------------------------------------------------- 1 | 14 | * @copyright 2005-2008 Janrain, Inc. 15 | * @license http://www.apache.org/licenses/LICENSE-2.0 Apache 16 | */ 17 | 18 | /** 19 | * Container for key-value/comma-newline OpenID format and parsing 20 | */ 21 | class Auth_OpenID_KVForm { 22 | /** 23 | * Convert an OpenID colon/newline separated string into an 24 | * associative array 25 | * 26 | * @static 27 | * @access private 28 | * @param string $kvs 29 | * @param bool $strict 30 | * @return array|bool 31 | */ 32 | static function toArray($kvs, $strict=false) 33 | { 34 | $lines = explode("\n", $kvs); 35 | 36 | $last = array_pop($lines); 37 | if ($last !== '') { 38 | array_push($lines, $last); 39 | if ($strict) { 40 | return false; 41 | } 42 | } 43 | 44 | $values = []; 45 | 46 | for ($lineno = 0; $lineno < count($lines); $lineno++) { 47 | $line = $lines[$lineno]; 48 | $kv = explode(':', $line, 2); 49 | if (count($kv) != 2) { 50 | if ($strict) { 51 | return false; 52 | } 53 | continue; 54 | } 55 | 56 | $key = $kv[0]; 57 | $tkey = trim($key); 58 | if ($tkey != $key) { 59 | if ($strict) { 60 | return false; 61 | } 62 | } 63 | 64 | $value = $kv[1]; 65 | $tval = trim($value); 66 | if ($tval != $value) { 67 | if ($strict) { 68 | return false; 69 | } 70 | } 71 | 72 | $values[$tkey] = $tval; 73 | } 74 | 75 | return $values; 76 | } 77 | 78 | /** 79 | * Convert an array into an OpenID colon/newline separated string 80 | * 81 | * @static 82 | * @access private 83 | * @param null|array $values 84 | * @return null|string 85 | */ 86 | static function fromArray($values) 87 | { 88 | if ($values === null) { 89 | return null; 90 | } 91 | 92 | ksort($values); 93 | 94 | $serialized = ''; 95 | foreach ($values as $key => $value) { 96 | if (is_array($value)) { 97 | list($key, $value) = [$value[0], $value[1]]; 98 | } 99 | 100 | if (strpos($key, ':') !== false) { 101 | return null; 102 | } 103 | 104 | if (strpos($key, "\n") !== false) { 105 | return null; 106 | } 107 | 108 | if (strpos($value, "\n") !== false) { 109 | return null; 110 | } 111 | $serialized .= "$key:$value\n"; 112 | } 113 | return $serialized; 114 | } 115 | } 116 | 117 | -------------------------------------------------------------------------------- /Auth/OpenID/Nonce.php: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | %s 9 | %s 10 | 11 | 12 | %s 13 |
    14 |

    %s

    15 | %s 16 |
    17 | 18 | '); 19 | 20 | define('logged_in_pat', 'You are logged in as %s (URL: %s)'); 21 | 22 | /** 23 | * HTTP response line contstants 24 | */ 25 | define('http_bad_request', 'HTTP/1.1 400 Bad Request'); 26 | define('http_found', 'HTTP/1.1 302 Found'); 27 | define('http_ok', 'HTTP/1.1 200 OK'); 28 | define('http_internal_error', 'HTTP/1.1 500 Internal Error'); 29 | 30 | /** 31 | * HTTP header constants 32 | */ 33 | define('header_connection_close', 'Connection: close'); 34 | define('header_content_text', 'Content-Type: text/plain; charset=us-ascii'); 35 | 36 | define('redirect_message', 37 | 'Please wait; you are being redirected to <%s>'); 38 | 39 | 40 | /** 41 | * Return a string containing an anchor tag containing the given URL 42 | * 43 | * The URL does not need to be quoted, but if text is passed in, then 44 | * it does. 45 | */ 46 | function link_render($url, $text=null) { 47 | $esc_url = htmlspecialchars($url, ENT_QUOTES); 48 | $text = ($text === null) ? $esc_url : $text; 49 | return sprintf('%s', $esc_url, $text); 50 | } 51 | 52 | /** 53 | * Return an HTTP redirect response 54 | */ 55 | function redirect_render($redir_url) 56 | { 57 | $headers = [ 58 | http_found, 59 | header_content_text, 60 | header_connection_close, 61 | 'Location: ' . $redir_url, 62 | ]; 63 | $body = sprintf(redirect_message, $redir_url); 64 | return [$headers, $body]; 65 | } 66 | 67 | function navigation_render($msg, $items) 68 | { 69 | $what = link_render(buildURL(), 'PHP OpenID Server'); 70 | if ($msg) { 71 | $what .= ' — ' . $msg; 72 | } 73 | if ($items) { 74 | $s = '

    ' . $what . '

      '; 75 | foreach ($items as $action => $text) { 76 | $url = buildURL($action); 77 | $s .= sprintf('
    • %s
    • ', link_render($url, $text)); 78 | } 79 | $s .= '
    '; 80 | } else { 81 | $s = '

    ' . $what . '

    '; 82 | } 83 | return sprintf('', $s); 84 | } 85 | 86 | /** 87 | * Render an HTML page 88 | */ 89 | function page_render($body, $user, $title, $h1=null, $login=false) 90 | { 91 | $h1 = $h1 ? $h1 : $title; 92 | 93 | if ($user) { 94 | $msg = sprintf(logged_in_pat, link_render(idURL($user), $user), 95 | link_render(idURL($user))); 96 | $nav = ['logout' => 'Log Out']; 97 | 98 | $navigation = navigation_render($msg, $nav); 99 | } else { 100 | if (!$login) { 101 | $msg = link_render(buildURL('login'), 'Log In'); 102 | $navigation = navigation_render($msg, []); 103 | } else { 104 | $navigation = ''; 105 | } 106 | } 107 | 108 | $style = getStyle(); 109 | $text = sprintf(page_template, $title, $style, $navigation, $h1, $body); 110 | // No special headers here 111 | $headers = []; 112 | return [$headers, $text]; 113 | } 114 | 115 | ?> -------------------------------------------------------------------------------- /Auth/OpenID/HMAC.php: -------------------------------------------------------------------------------- 1 | 13 | * @copyright 2005-2008 Janrain, Inc. 14 | * @license http://www.apache.org/licenses/LICENSE-2.0 Apache 15 | */ 16 | 17 | require_once 'Auth/OpenID.php'; 18 | 19 | /** 20 | * SHA1_BLOCKSIZE is this module's SHA1 blocksize used by the fallback 21 | * implementation. 22 | */ 23 | define('Auth_OpenID_SHA1_BLOCKSIZE', 64); 24 | 25 | function Auth_OpenID_SHA1($text) 26 | { 27 | if (function_exists('hash') && 28 | function_exists('hash_algos') && 29 | (in_array('sha1', hash_algos()))) { 30 | // PHP 5 case (sometimes): 'hash' available and 'sha1' algo 31 | // supported. 32 | return hash('sha1', $text, true); 33 | } else if (function_exists('sha1')) { 34 | // PHP 4 case: 'sha1' available. 35 | $hex = sha1($text); 36 | $raw = ''; 37 | for ($i = 0; $i < 40; $i += 2) { 38 | $hexcode = substr($hex, $i, 2); 39 | $charcode = (int)base_convert($hexcode, 16, 10); 40 | $raw .= chr($charcode); 41 | } 42 | return $raw; 43 | } else { 44 | // Explode. 45 | trigger_error('No SHA1 function found', E_USER_ERROR); 46 | return false; 47 | } 48 | } 49 | 50 | /** 51 | * Compute an HMAC/SHA1 hash. 52 | * 53 | * @access private 54 | * @param string $key The HMAC key 55 | * @param string $text The message text to hash 56 | * @return string $mac The MAC 57 | */ 58 | function Auth_OpenID_HMACSHA1($key, $text) 59 | { 60 | if (Auth_OpenID::bytes($key) > Auth_OpenID_SHA1_BLOCKSIZE) { 61 | $key = Auth_OpenID_SHA1($key); 62 | } 63 | 64 | if (function_exists('hash_hmac') && 65 | function_exists('hash_algos') && 66 | (in_array('sha1', hash_algos()))) { 67 | return hash_hmac('sha1', $text, $key, true); 68 | } 69 | // Home-made solution 70 | 71 | $key = str_pad($key, Auth_OpenID_SHA1_BLOCKSIZE, chr(0x00)); 72 | $ipad = str_repeat(chr(0x36), Auth_OpenID_SHA1_BLOCKSIZE); 73 | $opad = str_repeat(chr(0x5c), Auth_OpenID_SHA1_BLOCKSIZE); 74 | $hash1 = Auth_OpenID_SHA1(($key ^ $ipad) . $text); 75 | $hmac = Auth_OpenID_SHA1(($key ^ $opad) . $hash1); 76 | return $hmac; 77 | } 78 | 79 | if (function_exists('hash') && 80 | function_exists('hash_algos') && 81 | (in_array('sha256', hash_algos()))) { 82 | function Auth_OpenID_SHA256($text) 83 | { 84 | // PHP 5 case: 'hash' available and 'sha256' algo supported. 85 | return hash('sha256', $text, true); 86 | } 87 | define('Auth_OpenID_SHA256_SUPPORTED', true); 88 | } else { 89 | define('Auth_OpenID_SHA256_SUPPORTED', false); 90 | } 91 | 92 | if (function_exists('hash_hmac') && 93 | function_exists('hash_algos') && 94 | (in_array('sha256', hash_algos()))) { 95 | 96 | function Auth_OpenID_HMACSHA256($key, $text) 97 | { 98 | // Return raw MAC (not hex string). 99 | return hash_hmac('sha256', $text, $key, true); 100 | } 101 | 102 | define('Auth_OpenID_HMACSHA256_SUPPORTED', true); 103 | } else { 104 | define('Auth_OpenID_HMACSHA256_SUPPORTED', false); 105 | } 106 | 107 | -------------------------------------------------------------------------------- /examples/consumer/common.php: -------------------------------------------------------------------------------- 1 | 117 | -------------------------------------------------------------------------------- /examples/consumer/finish_auth.php: -------------------------------------------------------------------------------- 1 | complete($return_to); 17 | 18 | // Check the response status. 19 | if ($response->status == Auth_OpenID_CANCEL) { 20 | // This means the authentication was cancelled. 21 | $msg = 'Verification cancelled.'; 22 | } else if ($response->status == Auth_OpenID_FAILURE) { 23 | // Authentication failed; display the error message. 24 | $msg = "OpenID authentication failed: " . $response->message; 25 | } else if ($response->status == Auth_OpenID_SUCCESS) { 26 | // This means the authentication succeeded; extract the 27 | // identity URL and Simple Registration data (if it was 28 | // returned). 29 | $openid = $response->getDisplayIdentifier(); 30 | $esc_identity = escape($openid); 31 | 32 | $success = sprintf('You have successfully verified ' . 33 | '%s as your identity.', 34 | $esc_identity, $esc_identity); 35 | 36 | if ($response->endpoint->canonicalID) { 37 | $escaped_canonicalID = escape($response->endpoint->canonicalID); 38 | $success .= ' (XRI CanonicalID: '.$escaped_canonicalID.') '; 39 | } 40 | 41 | $sreg_resp = Auth_OpenID_SRegResponse::fromSuccessResponse($response); 42 | 43 | $sreg = $sreg_resp->contents(); 44 | 45 | if (@$sreg['email']) { 46 | $success .= " You also returned '".escape($sreg['email']). 47 | "' as your email."; 48 | } 49 | 50 | if (@$sreg['nickname']) { 51 | $success .= " Your nickname is '".escape($sreg['nickname']). 52 | "'."; 53 | } 54 | 55 | if (@$sreg['fullname']) { 56 | $success .= " Your fullname is '".escape($sreg['fullname']). 57 | "'."; 58 | } 59 | 60 | $pape_resp = Auth_OpenID_PAPE_Response::fromSuccessResponse($response); 61 | 62 | if ($pape_resp) { 63 | if ($pape_resp->auth_policies) { 64 | $success .= "

    The following PAPE policies affected the authentication:

      "; 65 | 66 | foreach ($pape_resp->auth_policies as $uri) { 67 | $escaped_uri = escape($uri); 68 | $success .= "
    • $escaped_uri
    • "; 69 | } 70 | 71 | $success .= "
    "; 72 | } else { 73 | $success .= "

    No PAPE policies affected the authentication.

    "; 74 | } 75 | 76 | if ($pape_resp->auth_age) { 77 | $age = escape($pape_resp->auth_age); 78 | $success .= "

    The authentication age returned by the " . 79 | "server is: ".$age."

    "; 80 | } 81 | 82 | if ($pape_resp->nist_auth_level) { 83 | $auth_level = escape($pape_resp->nist_auth_level); 84 | $success .= "

    The NIST auth level returned by the " . 85 | "server is: ".$auth_level."

    "; 86 | } 87 | 88 | } else { 89 | $success .= "

    No PAPE response was sent by the provider.

    "; 90 | } 91 | } 92 | 93 | include 'index.php'; 94 | } 95 | 96 | run(); 97 | 98 | ?> -------------------------------------------------------------------------------- /Auth/OpenID/DiffieHellman.php: -------------------------------------------------------------------------------- 1 | 13 | * @copyright 2005-2008 Janrain, Inc. 14 | * @license http://www.apache.org/licenses/LICENSE-2.0 Apache 15 | */ 16 | 17 | require_once 'Auth/OpenID.php'; 18 | require_once 'Auth/OpenID/BigMath.php'; 19 | 20 | function Auth_OpenID_getDefaultMod() 21 | { 22 | return '155172898181473697471232257763715539915724801'. 23 | '966915404479707795314057629378541917580651227423'. 24 | '698188993727816152646631438561595825688188889951'. 25 | '272158842675419950341258706556549803580104870537'. 26 | '681476726513255747040765857479291291572334510643'. 27 | '245094715007229621094194349783925984760375594985'. 28 | '848253359305585439638443'; 29 | } 30 | 31 | function Auth_OpenID_getDefaultGen() 32 | { 33 | return '2'; 34 | } 35 | 36 | /** 37 | * The Diffie-Hellman key exchange class. This class relies on 38 | * {@link Auth_OpenID_MathLibrary} to perform large number operations. 39 | * 40 | * @access private 41 | * @package OpenID 42 | */ 43 | class Auth_OpenID_DiffieHellman { 44 | 45 | public $mod; 46 | public $gen; 47 | public $private; 48 | /** @var Auth_OpenID_BcMathWrapper */ 49 | public $lib = null; 50 | 51 | function __construct($mod = null, $gen = null, 52 | $private = null, $lib = null) 53 | { 54 | if ($lib === null) { 55 | $this->lib = Auth_OpenID_getMathLib(); 56 | } else { 57 | $this->lib = $lib; 58 | } 59 | 60 | if ($mod === null) { 61 | $this->mod = $this->lib->init(Auth_OpenID_getDefaultMod()); 62 | } else { 63 | $this->mod = $mod; 64 | } 65 | 66 | if ($gen === null) { 67 | $this->gen = $this->lib->init(Auth_OpenID_getDefaultGen()); 68 | } else { 69 | $this->gen = $gen; 70 | } 71 | 72 | if ($private === null) { 73 | $r = $this->lib->rand($this->mod); 74 | $this->private = $this->lib->add($r, 1); 75 | } else { 76 | $this->private = $private; 77 | } 78 | 79 | $this->public = $this->lib->powmod($this->gen, $this->private, 80 | $this->mod); 81 | } 82 | 83 | function getSharedSecret($composite) 84 | { 85 | return $this->lib->powmod($composite, $this->private, $this->mod); 86 | } 87 | 88 | function getPublicKey() 89 | { 90 | return $this->public; 91 | } 92 | 93 | function usingDefaultValues() 94 | { 95 | return ($this->mod == Auth_OpenID_getDefaultMod() && 96 | $this->gen == Auth_OpenID_getDefaultGen()); 97 | } 98 | 99 | function xorSecret($composite, $secret, $hash_func) 100 | { 101 | $dh_shared = $this->getSharedSecret($composite); 102 | $dh_shared_str = $this->lib->longToBinary($dh_shared); 103 | $hash_dh_shared = $hash_func($dh_shared_str); 104 | 105 | $xsecret = ""; 106 | for ($i = 0; $i < Auth_OpenID::bytes($secret); $i++) { 107 | $xsecret .= chr(ord($secret[$i]) ^ ord($hash_dh_shared[$i])); 108 | } 109 | 110 | return $xsecret; 111 | } 112 | } 113 | 114 | 115 | -------------------------------------------------------------------------------- /admin/phpaliases.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """This script searches files for functions that are just aliases in 4 | PHP source code. This is not 100% reliable, so it should not be 5 | automated, but it's useful to run once in a while to make sure that 6 | all of the matches it finds are not really legitimate aliases. 7 | 8 | Usage: 9 | 10 | parse_aliases.py [PHP source code filename]... 11 | """ 12 | 13 | import sys 14 | 15 | # Fetch this URL to get the file that is parsed into the aliases list 16 | alias_url = 'http://www.zend.com/phpfunc/all_aliases.php' 17 | 18 | header_tok = ''; 19 | footer_tok = ''; 20 | 21 | # Example line of the table that we parse: 22 | # 'bzclosephp-src/ext/bz2/bz2.cfclose' 23 | 24 | import re 25 | 26 | line_re = re.compile(r''' 27 | \A 28 | 29 | ]+"> 30 | 31 | ([^<>]+) 32 | 33 | ]+">[^<>]+ 34 | 35 | 36 | (?: 37 | ]+\.php"> 38 | ( [^<>]+ ) 39 | 40 | | ( [^<>]+ ) 41 | ) 42 | 43 | 44 | 45 | 46 | \Z 47 | ''', re.VERBOSE) 48 | 49 | def parseString(s): 50 | _, rest = s.split(header_tok, 1) 51 | body, _ = rest.split(footer_tok, 1) 52 | 53 | lines = body.split('\n') 54 | assert [s.strip() for s in lines[-2:]] == ['', ''] 55 | assert lines[0].strip().startswith('|\$|)\s*\b(%s)\b' % ('|'.join(aliases.keys()))) 82 | 83 | def checkAliasesFile(alias_re, f): 84 | found = [] 85 | line_num = 1 86 | for line in f: 87 | for mo in alias_re.finditer(line): 88 | if mo.group(1): 89 | continue 90 | alias = mo.group(2) 91 | found.append((line_num, alias)) 92 | line_num += 1 93 | return found 94 | 95 | def checkAliases(alias_re, filename): 96 | return checkAliasesFile(alias_re, file(filename, 'r')) 97 | 98 | def checkAliasesFiles(alias_re, filenames): 99 | found = [] 100 | for filename in filenames: 101 | file_found = checkAliases(alias_re, filename) 102 | found.extend([(filename, n, a) for (n, a) in file_found]) 103 | return found 104 | 105 | def dumpResults(aliases, found, out=sys.stdout): 106 | for filename, n, a in found: 107 | print >>out, "%s:%d %s -> %s" % (filename, n, a, aliases[a]) 108 | 109 | def main(alias_file, *filenames): 110 | aliases = parseFileName(alias_file) 111 | alias_re = getAliasRE(aliases) 112 | found = checkAliasesFiles(alias_re, filenames) 113 | dumpResults(aliases, found) 114 | return found 115 | 116 | if __name__ == '__main__': 117 | found = main(*sys.argv[1:]) 118 | if found: 119 | sys.exit(1) 120 | -------------------------------------------------------------------------------- /Auth/OpenID/DumbStore.php: -------------------------------------------------------------------------------- 1 | 13 | * @copyright 2005-2008 Janrain, Inc. 14 | * @license http://www.apache.org/licenses/LICENSE-2.0 Apache 15 | */ 16 | 17 | /** 18 | * Import the interface for creating a new store class. 19 | */ 20 | require_once 'Auth/OpenID/Interface.php'; 21 | require_once 'Auth/OpenID/HMAC.php'; 22 | 23 | /** 24 | * This is a store for use in the worst case, when you have no way of 25 | * saving state on the consumer site. Using this store makes the 26 | * consumer vulnerable to replay attacks, as it's unable to use 27 | * nonces. Avoid using this store if it is at all possible. 28 | * 29 | * Most of the methods of this class are implementation details. 30 | * Users of this class need to worry only about the constructor. 31 | * 32 | * @package OpenID 33 | */ 34 | class Auth_OpenID_DumbStore extends Auth_OpenID_OpenIDStore { 35 | protected $auth_key; 36 | 37 | /** 38 | * Creates a new {@link Auth_OpenID_DumbStore} instance. For the security 39 | * of the tokens generated by the library, this class attempts to 40 | * at least have a secure implementation of getAuthKey. 41 | * 42 | * When you create an instance of this class, pass in a secret 43 | * phrase. The phrase is hashed with sha1 to make it the correct 44 | * length and form for an auth key. That allows you to use a long 45 | * string as the secret phrase, which means you can make it very 46 | * difficult to guess. 47 | * 48 | * Each {@link Auth_OpenID_DumbStore} instance that is created for use by 49 | * your consumer site needs to use the same $secret_phrase. 50 | * 51 | * @param string $secret_phrase The phrase used to create the auth 52 | * key returned by getAuthKey 53 | */ 54 | function __construct($secret_phrase) 55 | { 56 | $this->auth_key = Auth_OpenID_SHA1($secret_phrase); 57 | } 58 | 59 | /** 60 | * This implementation does nothing. 61 | * 62 | * @param string $server_url 63 | * @param Auth_OpenID_Association $association 64 | */ 65 | function storeAssociation($server_url, $association) 66 | { 67 | } 68 | 69 | /** 70 | * This implementation always returns null. 71 | * 72 | * @param string $server_url 73 | * @param null $handle 74 | * @return Auth_OpenID_Association|null 75 | */ 76 | function getAssociation($server_url, $handle = null) 77 | { 78 | return null; 79 | } 80 | 81 | /** 82 | * This implementation always returns false. 83 | * 84 | * @param string $server_url 85 | * @param string $handle 86 | * @return bool|mixed 87 | */ 88 | function removeAssociation($server_url, $handle) 89 | { 90 | return false; 91 | } 92 | 93 | /** 94 | * In a system truly limited to dumb mode, nonces must all be 95 | * accepted. This therefore always returns true, which makes 96 | * replay attacks feasible. 97 | * 98 | * @param string $server_url 99 | * @param int $timestamp 100 | * @param string $salt 101 | * @return bool 102 | */ 103 | function useNonce($server_url, $timestamp, $salt) 104 | { 105 | return true; 106 | } 107 | 108 | /** 109 | * This method returns the auth key generated by the constructor. 110 | */ 111 | function getAuthKey() 112 | { 113 | return $this->auth_key; 114 | } 115 | } 116 | 117 | -------------------------------------------------------------------------------- /Tests/Auth/Yadis/data/accept.txt: -------------------------------------------------------------------------------- 1 | # Accept: [Accept: header value from RFC2616, 2 | # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html] 3 | # Available: [whitespace-separated content types] 4 | # Expected: [Accept-header like list, containing the available content 5 | # types with their q-values] 6 | 7 | Accept: */* 8 | Available: text/plain 9 | Expected: text/plain; q=1.0 10 | 11 | Accept: */* 12 | Available: text/plain, text/html 13 | Expected: text/plain; q=1.0, text/html; q=1.0 14 | 15 | # The order matters 16 | Accept: */* 17 | Available: text/html, text/plain 18 | Expected: text/html; q=1.0, text/plain; q=1.0 19 | 20 | Accept: text/*, */*; q=0.9 21 | Available: text/plain, image/jpeg 22 | Expected: text/plain; q=1.0, image/jpeg; q=0.9 23 | 24 | Accept: text/*, */*; q=0.9 25 | Available: image/jpeg, text/plain 26 | Expected: text/plain; q=1.0, image/jpeg; q=0.9 27 | 28 | # wildcard subtypes still reject differing main types 29 | Accept: text/* 30 | Available: image/jpeg, text/plain 31 | Expected: text/plain; q=1.0 32 | 33 | Accept: text/html 34 | Available: text/html 35 | Expected: text/html; q=1.0 36 | 37 | Accept: text/html, text/* 38 | Available: text/html 39 | Expected: text/html; q=1.0 40 | 41 | Accept: text/html, text/* 42 | Available: text/plain, text/html 43 | Expected: text/plain; q=1.0, text/html; q=1.0 44 | 45 | Accept: text/html, text/*; q=0.9 46 | Available: text/plain, text/html 47 | Expected: text/html; q=1.0, text/plain; q=0.9 48 | 49 | # If a more specific type has a higher q-value, then the higher value wins 50 | Accept: text/*; q=0.9, text/html 51 | Available: text/plain, text/html 52 | Expected: text/html; q=1.0, text/plain; q=0.9 53 | 54 | Accept: */*, text/*; q=0.9, text/html; q=0.1 55 | Available: text/plain, text/html, image/monkeys 56 | Expected: image/monkeys; q=1.0, text/plain; q=0.9, text/html; q=0.1 57 | 58 | Accept: text/*, text/html; q=0 59 | Available: text/html 60 | Expected: 61 | 62 | Accept: text/*, text/html; q=0 63 | Available: text/html, text/plain 64 | Expected: text/plain; q=1.0 65 | 66 | Accept: text/html 67 | Available: text/plain 68 | Expected: 69 | 70 | Accept: application/xrds+xml, text/html; q=0.9 71 | Available: application/xrds+xml, text/html 72 | Expected: application/xrds+xml; q=1.0, text/html; q=0.9 73 | 74 | Accept: application/xrds+xml, */*; q=0.9 75 | Available: application/xrds+xml, text/html 76 | Expected: application/xrds+xml; q=1.0, text/html; q=0.9 77 | 78 | Accept: application/xrds+xml, application/xhtml+xml; q=0.9, text/html; q=0.8, text/xml; q=0.7 79 | Available: application/xrds+xml, text/html 80 | Expected: application/xrds+xml; q=1.0, text/html; q=0.8 81 | 82 | # See http://www.rfc-editor.org/rfc/rfc3023.txt, section A.13 83 | Accept: application/xrds 84 | Available: application/xrds+xml 85 | Expected: 86 | 87 | Accept: application/xrds+xml 88 | Available: application/xrds 89 | Expected: 90 | 91 | Accept: application/xml 92 | Available: application/xrds+xml 93 | Expected: 94 | 95 | Available: application/xrds+xml 96 | Accept: application/xml 97 | Expected: 98 | 99 | 100 | 101 | ################################################# 102 | # The tests below this line are documentation of how this library 103 | # works. If the implementation changes, it's acceptable to change the 104 | # test to reflect that. These are specified so that we can make sure 105 | # that the current implementation actually works the way that we 106 | # expect it to given these inputs. 107 | 108 | Accept: text/html;level=1 109 | Available: text/html 110 | Expected: text/html; q=1.0 111 | 112 | Accept: text/html; level=1, text/html; level=9; q=0.1 113 | Available: text/html 114 | Expected: text/html; q=1.0 115 | 116 | Accept: text/html; level=9; q=0.1, text/html; level=1 117 | Available: text/html 118 | Expected: text/html; q=1.0 119 | -------------------------------------------------------------------------------- /Auth/OpenID/CryptUtil.php: -------------------------------------------------------------------------------- 1 | 14 | * @copyright 2005-2008 Janrain, Inc. 15 | * @license http://www.apache.org/licenses/LICENSE-2.0 Apache 16 | */ 17 | 18 | if (!defined('Auth_OpenID_RAND_SOURCE')) { 19 | /** 20 | * The filename for a source of random bytes. Define this yourself 21 | * if you have a different source of randomness. 22 | */ 23 | define('Auth_OpenID_RAND_SOURCE', '/dev/urandom'); 24 | } 25 | 26 | class Auth_OpenID_CryptUtil { 27 | /** 28 | * Get the specified number of random bytes. 29 | * 30 | * Attempts to use a cryptographically secure (not predictable) 31 | * source of randomness if available. If there is no high-entropy 32 | * randomness source available, it will fail. As a last resort, 33 | * for non-critical systems, define 34 | * Auth_OpenID_RAND_SOURCE as null, and 35 | * the code will fall back on a pseudo-random number generator. 36 | * 37 | * @param int $num_bytes The length of the return value 38 | * @return string $bytes random bytes 39 | */ 40 | static function getBytes($num_bytes) 41 | { 42 | static $f = null; 43 | if ($f === null) { 44 | if (Auth_OpenID_RAND_SOURCE === null) { 45 | $f = false; 46 | } else { 47 | $f = @fopen(Auth_OpenID_RAND_SOURCE, "r"); 48 | if ($f === false) { 49 | $msg = 'Define Auth_OpenID_RAND_SOURCE as null to ' . 50 | ' continue with an insecure random number generator.'; 51 | trigger_error($msg, E_USER_ERROR); 52 | } 53 | } 54 | } 55 | if ($f === false) { 56 | // pseudorandom used 57 | $bytes = ''; 58 | for ($i = 0; $i < $num_bytes; $i += 4) { 59 | $bytes .= pack('L', mt_rand()); 60 | } 61 | $bytes = substr($bytes, 0, $num_bytes); 62 | } else { 63 | $bytes = fread($f, $num_bytes); 64 | } 65 | return $bytes; 66 | } 67 | 68 | /** 69 | * Produce a string of length random bytes, chosen from chrs. If 70 | * $chrs is null, the resulting string may contain any characters. 71 | * 72 | * @param integer $length The length of the resulting 73 | * randomly-generated string 74 | * @param string|null $population A string of characters from which to choose 75 | * to build the new string 76 | * @return string $result A string of randomly-chosen characters 77 | * from $chrs 78 | */ 79 | static function randomString($length, $population = null) 80 | { 81 | if ($population === null) { 82 | return Auth_OpenID_CryptUtil::getBytes($length); 83 | } 84 | 85 | $popsize = strlen($population); 86 | 87 | if ($popsize > 256) { 88 | $msg = 'More than 256 characters supplied to ' . __FUNCTION__; 89 | trigger_error($msg, E_USER_ERROR); 90 | } 91 | 92 | $duplicate = 256 % $popsize; 93 | 94 | $str = ""; 95 | for ($i = 0; $i < $length; $i++) { 96 | do { 97 | $n = ord(Auth_OpenID_CryptUtil::getBytes(1)); 98 | } while ($n < $duplicate); 99 | 100 | $n %= $popsize; 101 | $str .= $population[$n]; 102 | } 103 | 104 | return $str; 105 | } 106 | 107 | static function constEq($s1, $s2) 108 | { 109 | if (strlen($s1) != strlen($s2)) { 110 | return false; 111 | } 112 | 113 | $result = true; 114 | $length = strlen($s1); 115 | for ($i = 0; $i < $length; $i++) { 116 | $result &= ($s1[$i] == $s2[$i]); 117 | } 118 | return $result; 119 | } 120 | } 121 | 122 | -------------------------------------------------------------------------------- /Tests/Auth/Yadis/data/test1-parsehtml.txt: -------------------------------------------------------------------------------- 1 | found 2 | 3 | 4 | 5 | found 6 | 7 | 8 | 9 | found 10 | 11 | 12 | 13 | found 14 | 15 | 16 | 17 | found 18 | 19 | 20 | 21 | found 22 | 23 | 24 | 25 | found 26 | 27 | 28 | 29 | found 30 | 31 | 32 | 33 | EOF 34 | 35 |