xref: /plugin/authssocas/vendor/apereo/phpcas/source/CAS.php (revision d10b5556242e78d8a430c323b91984ec16415a46)
1*d10b5556SXylle<?php
2*d10b5556SXylle
3*d10b5556SXylle/**
4*d10b5556SXylle * Licensed to Jasig under one or more contributor license
5*d10b5556SXylle * agreements. See the NOTICE file distributed with this work for
6*d10b5556SXylle * additional information regarding copyright ownership.
7*d10b5556SXylle *
8*d10b5556SXylle * Jasig licenses this file to you under the Apache License,
9*d10b5556SXylle * Version 2.0 (the "License"); you may not use this file except in
10*d10b5556SXylle * compliance with the License. You may obtain a copy of the License at:
11*d10b5556SXylle *
12*d10b5556SXylle * http://www.apache.org/licenses/LICENSE-2.0
13*d10b5556SXylle *
14*d10b5556SXylle * Unless required by applicable law or agreed to in writing, software
15*d10b5556SXylle * distributed under the License is distributed on an "AS IS" BASIS,
16*d10b5556SXylle * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17*d10b5556SXylle * See the License for the specific language governing permissions and
18*d10b5556SXylle * limitations under the License.
19*d10b5556SXylle *
20*d10b5556SXylle *
21*d10b5556SXylle *
22*d10b5556SXylle * Interface class of the phpCAS library
23*d10b5556SXylle * PHP Version 7
24*d10b5556SXylle *
25*d10b5556SXylle * @file     CAS/CAS.php
26*d10b5556SXylle * @category Authentication
27*d10b5556SXylle * @package  PhpCAS
28*d10b5556SXylle * @author   Pascal Aubry <pascal.aubry@univ-rennes1.fr>
29*d10b5556SXylle * @author   Olivier Berger <olivier.berger@it-sudparis.eu>
30*d10b5556SXylle * @author   Brett Bieber <brett.bieber@gmail.com>
31*d10b5556SXylle * @author   Joachim Fritschi <jfritschi@freenet.de>
32*d10b5556SXylle * @author   Adam Franco <afranco@middlebury.edu>
33*d10b5556SXylle * @license  http://www.apache.org/licenses/LICENSE-2.0  Apache License 2.0
34*d10b5556SXylle * @link     https://wiki.jasig.org/display/CASC/phpCAS
35*d10b5556SXylle * @ingroup public
36*d10b5556SXylle */
37*d10b5556SXylle
38*d10b5556SXylleuse Psr\Log\LoggerInterface;
39*d10b5556SXylle
40*d10b5556SXylle//
41*d10b5556SXylle// hack by Vangelis Haniotakis to handle the absence of $_SERVER['REQUEST_URI']
42*d10b5556SXylle// in IIS
43*d10b5556SXylle//
44*d10b5556SXylleif (!isset($_SERVER['REQUEST_URI']) && isset($_SERVER['SCRIPT_NAME']) && isset($_SERVER['QUERY_STRING'])) {
45*d10b5556SXylle    $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] . '?' . $_SERVER['QUERY_STRING'];
46*d10b5556SXylle}
47*d10b5556SXylle
48*d10b5556SXylle
49*d10b5556SXylle// ########################################################################
50*d10b5556SXylle//  CONSTANTS
51*d10b5556SXylle// ########################################################################
52*d10b5556SXylle
53*d10b5556SXylle// ------------------------------------------------------------------------
54*d10b5556SXylle//  CAS VERSIONS
55*d10b5556SXylle// ------------------------------------------------------------------------
56*d10b5556SXylle
57*d10b5556SXylle/**
58*d10b5556SXylle * phpCAS version. accessible for the user by phpCAS::getVersion().
59*d10b5556SXylle */
60*d10b5556SXylledefine('PHPCAS_VERSION', '1.6.1');
61*d10b5556SXylle
62*d10b5556SXylle/**
63*d10b5556SXylle * @addtogroup public
64*d10b5556SXylle * @{
65*d10b5556SXylle */
66*d10b5556SXylle
67*d10b5556SXylle/**
68*d10b5556SXylle * phpCAS supported protocols. accessible for the user by phpCAS::getSupportedProtocols().
69*d10b5556SXylle */
70*d10b5556SXylle
71*d10b5556SXylle/**
72*d10b5556SXylle * CAS version 1.0
73*d10b5556SXylle */
74*d10b5556SXylledefine("CAS_VERSION_1_0", '1.0');
75*d10b5556SXylle/*!
76*d10b5556SXylle * CAS version 2.0
77*d10b5556SXylle*/
78*d10b5556SXylledefine("CAS_VERSION_2_0", '2.0');
79*d10b5556SXylle/**
80*d10b5556SXylle * CAS version 3.0
81*d10b5556SXylle */
82*d10b5556SXylledefine("CAS_VERSION_3_0", '3.0');
83*d10b5556SXylle
84*d10b5556SXylle// ------------------------------------------------------------------------
85*d10b5556SXylle//  SAML defines
86*d10b5556SXylle// ------------------------------------------------------------------------
87*d10b5556SXylle
88*d10b5556SXylle/**
89*d10b5556SXylle * SAML protocol
90*d10b5556SXylle */
91*d10b5556SXylledefine("SAML_VERSION_1_1", 'S1');
92*d10b5556SXylle
93*d10b5556SXylle/**
94*d10b5556SXylle * XML header for SAML POST
95*d10b5556SXylle */
96*d10b5556SXylledefine("SAML_XML_HEADER", '<?xml version="1.0" encoding="UTF-8"?>');
97*d10b5556SXylle
98*d10b5556SXylle/**
99*d10b5556SXylle * SOAP envelope for SAML POST
100*d10b5556SXylle */
101*d10b5556SXylledefine("SAML_SOAP_ENV", '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/>');
102*d10b5556SXylle
103*d10b5556SXylle/**
104*d10b5556SXylle * SOAP body for SAML POST
105*d10b5556SXylle */
106*d10b5556SXylledefine("SAML_SOAP_BODY", '<SOAP-ENV:Body>');
107*d10b5556SXylle
108*d10b5556SXylle/**
109*d10b5556SXylle * SAMLP request
110*d10b5556SXylle */
111*d10b5556SXylledefine("SAMLP_REQUEST", '<samlp:Request xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol"  MajorVersion="1" MinorVersion="1" RequestID="_192.168.16.51.1024506224022" IssueInstant="2002-06-19T17:03:44.022Z">');
112*d10b5556SXylledefine("SAMLP_REQUEST_CLOSE", '</samlp:Request>');
113*d10b5556SXylle
114*d10b5556SXylle/**
115*d10b5556SXylle * SAMLP artifact tag (for the ticket)
116*d10b5556SXylle */
117*d10b5556SXylledefine("SAML_ASSERTION_ARTIFACT", '<samlp:AssertionArtifact>');
118*d10b5556SXylle
119*d10b5556SXylle/**
120*d10b5556SXylle * SAMLP close
121*d10b5556SXylle */
122*d10b5556SXylledefine("SAML_ASSERTION_ARTIFACT_CLOSE", '</samlp:AssertionArtifact>');
123*d10b5556SXylle
124*d10b5556SXylle/**
125*d10b5556SXylle * SOAP body close
126*d10b5556SXylle */
127*d10b5556SXylledefine("SAML_SOAP_BODY_CLOSE", '</SOAP-ENV:Body>');
128*d10b5556SXylle
129*d10b5556SXylle/**
130*d10b5556SXylle * SOAP envelope close
131*d10b5556SXylle */
132*d10b5556SXylledefine("SAML_SOAP_ENV_CLOSE", '</SOAP-ENV:Envelope>');
133*d10b5556SXylle
134*d10b5556SXylle/**
135*d10b5556SXylle * SAML Attributes
136*d10b5556SXylle */
137*d10b5556SXylledefine("SAML_ATTRIBUTES", 'SAMLATTRIBS');
138*d10b5556SXylle
139*d10b5556SXylle/** @} */
140*d10b5556SXylle/**
141*d10b5556SXylle * @addtogroup publicPGTStorage
142*d10b5556SXylle * @{
143*d10b5556SXylle */
144*d10b5556SXylle// ------------------------------------------------------------------------
145*d10b5556SXylle//  FILE PGT STORAGE
146*d10b5556SXylle// ------------------------------------------------------------------------
147*d10b5556SXylle/**
148*d10b5556SXylle * Default path used when storing PGT's to file
149*d10b5556SXylle */
150*d10b5556SXylledefine("CAS_PGT_STORAGE_FILE_DEFAULT_PATH", session_save_path());
151*d10b5556SXylle/** @} */
152*d10b5556SXylle// ------------------------------------------------------------------------
153*d10b5556SXylle// SERVICE ACCESS ERRORS
154*d10b5556SXylle// ------------------------------------------------------------------------
155*d10b5556SXylle/**
156*d10b5556SXylle * @addtogroup publicServices
157*d10b5556SXylle * @{
158*d10b5556SXylle */
159*d10b5556SXylle
160*d10b5556SXylle/**
161*d10b5556SXylle * phpCAS::service() error code on success
162*d10b5556SXylle */
163*d10b5556SXylledefine("PHPCAS_SERVICE_OK", 0);
164*d10b5556SXylle/**
165*d10b5556SXylle * phpCAS::service() error code when the PT could not retrieve because
166*d10b5556SXylle * the CAS server did not respond.
167*d10b5556SXylle */
168*d10b5556SXylledefine("PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE", 1);
169*d10b5556SXylle/**
170*d10b5556SXylle * phpCAS::service() error code when the PT could not retrieve because
171*d10b5556SXylle * the response of the CAS server was ill-formed.
172*d10b5556SXylle */
173*d10b5556SXylledefine("PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE", 2);
174*d10b5556SXylle/**
175*d10b5556SXylle * phpCAS::service() error code when the PT could not retrieve because
176*d10b5556SXylle * the CAS server did not want to.
177*d10b5556SXylle */
178*d10b5556SXylledefine("PHPCAS_SERVICE_PT_FAILURE", 3);
179*d10b5556SXylle/**
180*d10b5556SXylle * phpCAS::service() error code when the service was not available.
181*d10b5556SXylle */
182*d10b5556SXylledefine("PHPCAS_SERVICE_NOT_AVAILABLE", 4);
183*d10b5556SXylle
184*d10b5556SXylle// ------------------------------------------------------------------------
185*d10b5556SXylle// SERVICE TYPES
186*d10b5556SXylle// ------------------------------------------------------------------------
187*d10b5556SXylle/**
188*d10b5556SXylle * phpCAS::getProxiedService() type for HTTP GET
189*d10b5556SXylle */
190*d10b5556SXylledefine("PHPCAS_PROXIED_SERVICE_HTTP_GET", 'CAS_ProxiedService_Http_Get');
191*d10b5556SXylle/**
192*d10b5556SXylle * phpCAS::getProxiedService() type for HTTP POST
193*d10b5556SXylle */
194*d10b5556SXylledefine("PHPCAS_PROXIED_SERVICE_HTTP_POST", 'CAS_ProxiedService_Http_Post');
195*d10b5556SXylle/**
196*d10b5556SXylle * phpCAS::getProxiedService() type for IMAP
197*d10b5556SXylle */
198*d10b5556SXylledefine("PHPCAS_PROXIED_SERVICE_IMAP", 'CAS_ProxiedService_Imap');
199*d10b5556SXylle
200*d10b5556SXylle
201*d10b5556SXylle/** @} */
202*d10b5556SXylle// ------------------------------------------------------------------------
203*d10b5556SXylle//  LANGUAGES
204*d10b5556SXylle// ------------------------------------------------------------------------
205*d10b5556SXylle/**
206*d10b5556SXylle * @addtogroup publicLang
207*d10b5556SXylle * @{
208*d10b5556SXylle */
209*d10b5556SXylle
210*d10b5556SXylledefine("PHPCAS_LANG_ENGLISH", 'CAS_Languages_English');
211*d10b5556SXylledefine("PHPCAS_LANG_FRENCH", 'CAS_Languages_French');
212*d10b5556SXylledefine("PHPCAS_LANG_GREEK", 'CAS_Languages_Greek');
213*d10b5556SXylledefine("PHPCAS_LANG_GERMAN", 'CAS_Languages_German');
214*d10b5556SXylledefine("PHPCAS_LANG_JAPANESE", 'CAS_Languages_Japanese');
215*d10b5556SXylledefine("PHPCAS_LANG_SPANISH", 'CAS_Languages_Spanish');
216*d10b5556SXylledefine("PHPCAS_LANG_CATALAN", 'CAS_Languages_Catalan');
217*d10b5556SXylledefine("PHPCAS_LANG_CHINESE_SIMPLIFIED", 'CAS_Languages_ChineseSimplified');
218*d10b5556SXylledefine("PHPCAS_LANG_GALEGO", 'CAS_Languages_Galego');
219*d10b5556SXylledefine("PHPCAS_LANG_PORTUGUESE", 'CAS_Languages_Portuguese');
220*d10b5556SXylle
221*d10b5556SXylle/** @} */
222*d10b5556SXylle
223*d10b5556SXylle/**
224*d10b5556SXylle * @addtogroup internalLang
225*d10b5556SXylle * @{
226*d10b5556SXylle */
227*d10b5556SXylle
228*d10b5556SXylle/**
229*d10b5556SXylle * phpCAS default language (when phpCAS::setLang() is not used)
230*d10b5556SXylle */
231*d10b5556SXylledefine("PHPCAS_LANG_DEFAULT", PHPCAS_LANG_ENGLISH);
232*d10b5556SXylle
233*d10b5556SXylle/** @} */
234*d10b5556SXylle// ------------------------------------------------------------------------
235*d10b5556SXylle//  DEBUG
236*d10b5556SXylle// ------------------------------------------------------------------------
237*d10b5556SXylle/**
238*d10b5556SXylle * @addtogroup publicDebug
239*d10b5556SXylle * @{
240*d10b5556SXylle */
241*d10b5556SXylle
242*d10b5556SXylle/**
243*d10b5556SXylle * The default directory for the debug file under Unix.
244*d10b5556SXylle * @return  string directory for the debug file
245*d10b5556SXylle */
246*d10b5556SXyllefunction gettmpdir() {
247*d10b5556SXylleif (!empty($_ENV['TMP'])) { return realpath($_ENV['TMP']); }
248*d10b5556SXylleif (!empty($_ENV['TMPDIR'])) { return realpath( $_ENV['TMPDIR']); }
249*d10b5556SXylleif (!empty($_ENV['TEMP'])) { return realpath( $_ENV['TEMP']); }
250*d10b5556SXyllereturn "/tmp";
251*d10b5556SXylle}
252*d10b5556SXylledefine('DEFAULT_DEBUG_DIR', gettmpdir()."/");
253*d10b5556SXylle
254*d10b5556SXylle/** @} */
255*d10b5556SXylle
256*d10b5556SXylle// include the class autoloader
257*d10b5556SXyllerequire_once __DIR__ . '/CAS/Autoload.php';
258*d10b5556SXylle
259*d10b5556SXylle/**
260*d10b5556SXylle * The phpCAS class is a simple container for the phpCAS library. It provides CAS
261*d10b5556SXylle * authentication for web applications written in PHP.
262*d10b5556SXylle *
263*d10b5556SXylle * @ingroup public
264*d10b5556SXylle * @class phpCAS
265*d10b5556SXylle * @category Authentication
266*d10b5556SXylle * @package  PhpCAS
267*d10b5556SXylle * @author   Pascal Aubry <pascal.aubry@univ-rennes1.fr>
268*d10b5556SXylle * @author   Olivier Berger <olivier.berger@it-sudparis.eu>
269*d10b5556SXylle * @author   Brett Bieber <brett.bieber@gmail.com>
270*d10b5556SXylle * @author   Joachim Fritschi <jfritschi@freenet.de>
271*d10b5556SXylle * @author   Adam Franco <afranco@middlebury.edu>
272*d10b5556SXylle * @license  http://www.apache.org/licenses/LICENSE-2.0  Apache License 2.0
273*d10b5556SXylle * @link     https://wiki.jasig.org/display/CASC/phpCAS
274*d10b5556SXylle */
275*d10b5556SXylle
276*d10b5556SXylleclass phpCAS
277*d10b5556SXylle{
278*d10b5556SXylle
279*d10b5556SXylle    /**
280*d10b5556SXylle     * This variable is used by the interface class phpCAS.
281*d10b5556SXylle     *
282*d10b5556SXylle     * @var CAS_Client
283*d10b5556SXylle     * @hideinitializer
284*d10b5556SXylle     */
285*d10b5556SXylle    private static $_PHPCAS_CLIENT;
286*d10b5556SXylle
287*d10b5556SXylle    /**
288*d10b5556SXylle     * @var array
289*d10b5556SXylle     * This variable is used to store where the initializer is called from
290*d10b5556SXylle     * (to print a comprehensive error in case of multiple calls).
291*d10b5556SXylle     *
292*d10b5556SXylle     * @hideinitializer
293*d10b5556SXylle     */
294*d10b5556SXylle    private static $_PHPCAS_INIT_CALL;
295*d10b5556SXylle
296*d10b5556SXylle    /**
297*d10b5556SXylle     * @var array
298*d10b5556SXylle     * This variable is used to store phpCAS debug mode.
299*d10b5556SXylle     *
300*d10b5556SXylle     * @hideinitializer
301*d10b5556SXylle     */
302*d10b5556SXylle    private static $_PHPCAS_DEBUG;
303*d10b5556SXylle
304*d10b5556SXylle    /**
305*d10b5556SXylle     * This variable is used to enable verbose mode
306*d10b5556SXylle     * This pevents debug info to be show to the user. Since it's a security
307*d10b5556SXylle     * feature the default is false
308*d10b5556SXylle     *
309*d10b5556SXylle     * @hideinitializer
310*d10b5556SXylle     */
311*d10b5556SXylle    private static $_PHPCAS_VERBOSE = false;
312*d10b5556SXylle
313*d10b5556SXylle
314*d10b5556SXylle    // ########################################################################
315*d10b5556SXylle    //  INITIALIZATION
316*d10b5556SXylle    // ########################################################################
317*d10b5556SXylle
318*d10b5556SXylle    /**
319*d10b5556SXylle     * @addtogroup publicInit
320*d10b5556SXylle     * @{
321*d10b5556SXylle     */
322*d10b5556SXylle
323*d10b5556SXylle    /**
324*d10b5556SXylle     * phpCAS client initializer.
325*d10b5556SXylle     *
326*d10b5556SXylle     * @param string                   $server_version  the version of the CAS server
327*d10b5556SXylle     * @param string                   $server_hostname the hostname of the CAS server
328*d10b5556SXylle     * @param int                      $server_port     the port the CAS server is running on
329*d10b5556SXylle     * @param string                   $server_uri      the URI the CAS server is responding on
330*d10b5556SXylle     * @param string|string[]|CAS_ServiceBaseUrl_Interface
331*d10b5556SXylle     *                                 $service_base_url the base URL (protocol, host and the
332*d10b5556SXylle     *                                                  optional port) of the CAS client; pass
333*d10b5556SXylle     *                                                  in an array to use auto discovery with
334*d10b5556SXylle     *                                                  an allowlist; pass in
335*d10b5556SXylle     *                                                  CAS_ServiceBaseUrl_Interface for custom
336*d10b5556SXylle     *                                                  behavior. Added in 1.6.0. Similar to
337*d10b5556SXylle     *                                                  serverName config in other CAS clients.
338*d10b5556SXylle     * @param bool                     $changeSessionID Allow phpCAS to change the session_id
339*d10b5556SXylle     *                                                  (Single Sign Out/handleLogoutRequests
340*d10b5556SXylle     *                                                  is based on that change)
341*d10b5556SXylle     * @param \SessionHandlerInterface $sessionHandler  the session handler
342*d10b5556SXylle     *
343*d10b5556SXylle     * @return void a newly created CAS_Client object
344*d10b5556SXylle     * @note Only one of the phpCAS::client() and phpCAS::proxy functions should be
345*d10b5556SXylle     * called, only once, and before all other methods (except phpCAS::getVersion()
346*d10b5556SXylle     * and phpCAS::setDebug()).
347*d10b5556SXylle     */
348*d10b5556SXylle    public static function client($server_version, $server_hostname,
349*d10b5556SXylle        $server_port, $server_uri, $service_base_url,
350*d10b5556SXylle        $changeSessionID = true, \SessionHandlerInterface $sessionHandler = null
351*d10b5556SXylle    ) {
352*d10b5556SXylle        phpCAS :: traceBegin();
353*d10b5556SXylle        if (is_object(self::$_PHPCAS_CLIENT)) {
354*d10b5556SXylle            phpCAS :: error(self::$_PHPCAS_INIT_CALL['method'] . '() has already been called (at ' . self::$_PHPCAS_INIT_CALL['file'] . ':' . self::$_PHPCAS_INIT_CALL['line'] . ')');
355*d10b5556SXylle        }
356*d10b5556SXylle
357*d10b5556SXylle        // store where the initializer is called from
358*d10b5556SXylle        $dbg = debug_backtrace();
359*d10b5556SXylle        self::$_PHPCAS_INIT_CALL = array (
360*d10b5556SXylle            'done' => true,
361*d10b5556SXylle            'file' => $dbg[0]['file'],
362*d10b5556SXylle            'line' => $dbg[0]['line'],
363*d10b5556SXylle            'method' => __CLASS__ . '::' . __FUNCTION__
364*d10b5556SXylle        );
365*d10b5556SXylle
366*d10b5556SXylle        // initialize the object $_PHPCAS_CLIENT
367*d10b5556SXylle        try {
368*d10b5556SXylle            self::$_PHPCAS_CLIENT = new CAS_Client(
369*d10b5556SXylle                $server_version, false, $server_hostname, $server_port, $server_uri, $service_base_url,
370*d10b5556SXylle                $changeSessionID, $sessionHandler
371*d10b5556SXylle            );
372*d10b5556SXylle        } catch (Exception $e) {
373*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
374*d10b5556SXylle        }
375*d10b5556SXylle        phpCAS :: traceEnd();
376*d10b5556SXylle    }
377*d10b5556SXylle
378*d10b5556SXylle    /**
379*d10b5556SXylle     * phpCAS proxy initializer.
380*d10b5556SXylle     *
381*d10b5556SXylle     * @param string                   $server_version  the version of the CAS server
382*d10b5556SXylle     * @param string                   $server_hostname the hostname of the CAS server
383*d10b5556SXylle     * @param string                   $server_port     the port the CAS server is running on
384*d10b5556SXylle     * @param string                   $server_uri      the URI the CAS server is responding on
385*d10b5556SXylle     * @param string|string[]|CAS_ServiceBaseUrl_Interface
386*d10b5556SXylle     *                                 $service_base_url the base URL (protocol, host and the
387*d10b5556SXylle     *                                                  optional port) of the CAS client; pass
388*d10b5556SXylle     *                                                  in an array to use auto discovery with
389*d10b5556SXylle     *                                                  an allowlist; pass in
390*d10b5556SXylle     *                                                  CAS_ServiceBaseUrl_Interface for custom
391*d10b5556SXylle     *                                                  behavior. Added in 1.6.0. Similar to
392*d10b5556SXylle     *                                                  serverName config in other CAS clients.
393*d10b5556SXylle     * @param bool                     $changeSessionID Allow phpCAS to change the session_id
394*d10b5556SXylle     *                                                  (Single Sign Out/handleLogoutRequests
395*d10b5556SXylle     *                                                  is based on that change)
396*d10b5556SXylle     * @param \SessionHandlerInterface $sessionHandler  the session handler
397*d10b5556SXylle     *
398*d10b5556SXylle     * @return void a newly created CAS_Client object
399*d10b5556SXylle     * @note Only one of the phpCAS::client() and phpCAS::proxy functions should be
400*d10b5556SXylle     * called, only once, and before all other methods (except phpCAS::getVersion()
401*d10b5556SXylle     * and phpCAS::setDebug()).
402*d10b5556SXylle     */
403*d10b5556SXylle    public static function proxy($server_version, $server_hostname,
404*d10b5556SXylle        $server_port, $server_uri, $service_base_url,
405*d10b5556SXylle        $changeSessionID = true, \SessionHandlerInterface $sessionHandler = null
406*d10b5556SXylle    ) {
407*d10b5556SXylle        phpCAS :: traceBegin();
408*d10b5556SXylle        if (is_object(self::$_PHPCAS_CLIENT)) {
409*d10b5556SXylle            phpCAS :: error(self::$_PHPCAS_INIT_CALL['method'] . '() has already been called (at ' . self::$_PHPCAS_INIT_CALL['file'] . ':' . self::$_PHPCAS_INIT_CALL['line'] . ')');
410*d10b5556SXylle        }
411*d10b5556SXylle
412*d10b5556SXylle        // store where the initialzer is called from
413*d10b5556SXylle        $dbg = debug_backtrace();
414*d10b5556SXylle        self::$_PHPCAS_INIT_CALL = array (
415*d10b5556SXylle            'done' => true,
416*d10b5556SXylle            'file' => $dbg[0]['file'],
417*d10b5556SXylle            'line' => $dbg[0]['line'],
418*d10b5556SXylle            'method' => __CLASS__ . '::' . __FUNCTION__
419*d10b5556SXylle        );
420*d10b5556SXylle
421*d10b5556SXylle        // initialize the object $_PHPCAS_CLIENT
422*d10b5556SXylle        try {
423*d10b5556SXylle            self::$_PHPCAS_CLIENT = new CAS_Client(
424*d10b5556SXylle                $server_version, true, $server_hostname, $server_port, $server_uri, $service_base_url,
425*d10b5556SXylle                $changeSessionID, $sessionHandler
426*d10b5556SXylle            );
427*d10b5556SXylle        } catch (Exception $e) {
428*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
429*d10b5556SXylle        }
430*d10b5556SXylle        phpCAS :: traceEnd();
431*d10b5556SXylle    }
432*d10b5556SXylle
433*d10b5556SXylle    /**
434*d10b5556SXylle     * Answer whether or not the client or proxy has been initialized
435*d10b5556SXylle     *
436*d10b5556SXylle     * @return bool
437*d10b5556SXylle     */
438*d10b5556SXylle    public static function isInitialized ()
439*d10b5556SXylle    {
440*d10b5556SXylle        return (is_object(self::$_PHPCAS_CLIENT));
441*d10b5556SXylle    }
442*d10b5556SXylle
443*d10b5556SXylle    /** @} */
444*d10b5556SXylle    // ########################################################################
445*d10b5556SXylle    //  DEBUGGING
446*d10b5556SXylle    // ########################################################################
447*d10b5556SXylle
448*d10b5556SXylle    /**
449*d10b5556SXylle     * @addtogroup publicDebug
450*d10b5556SXylle     * @{
451*d10b5556SXylle     */
452*d10b5556SXylle
453*d10b5556SXylle    /**
454*d10b5556SXylle     * Set/unset PSR-3 logger
455*d10b5556SXylle     *
456*d10b5556SXylle     * @param LoggerInterface $logger the PSR-3 logger used for logging, or
457*d10b5556SXylle     * null to stop logging.
458*d10b5556SXylle     *
459*d10b5556SXylle     * @return void
460*d10b5556SXylle     */
461*d10b5556SXylle    public static function setLogger($logger = null)
462*d10b5556SXylle    {
463*d10b5556SXylle        if (empty(self::$_PHPCAS_DEBUG['unique_id'])) {
464*d10b5556SXylle            self::$_PHPCAS_DEBUG['unique_id'] = substr(strtoupper(md5(uniqid(''))), 0, 4);
465*d10b5556SXylle        }
466*d10b5556SXylle        self::$_PHPCAS_DEBUG['logger'] = $logger;
467*d10b5556SXylle        self::$_PHPCAS_DEBUG['indent'] = 0;
468*d10b5556SXylle        phpCAS :: trace('START ('.date("Y-m-d H:i:s").') phpCAS-' . PHPCAS_VERSION . ' ******************');
469*d10b5556SXylle    }
470*d10b5556SXylle
471*d10b5556SXylle    /**
472*d10b5556SXylle     * Set/unset debug mode
473*d10b5556SXylle     *
474*d10b5556SXylle     * @param string $filename the name of the file used for logging, or false
475*d10b5556SXylle     * to stop debugging.
476*d10b5556SXylle     *
477*d10b5556SXylle     * @return void
478*d10b5556SXylle     *
479*d10b5556SXylle     * @deprecated
480*d10b5556SXylle     */
481*d10b5556SXylle    public static function setDebug($filename = '')
482*d10b5556SXylle    {
483*d10b5556SXylle        trigger_error('phpCAS::setDebug() is deprecated in favor of phpCAS::setLogger().', E_USER_DEPRECATED);
484*d10b5556SXylle
485*d10b5556SXylle        if ($filename != false && gettype($filename) != 'string') {
486*d10b5556SXylle            phpCAS :: error('type mismatched for parameter $dbg (should be false or the name of the log file)');
487*d10b5556SXylle        }
488*d10b5556SXylle        if ($filename === false) {
489*d10b5556SXylle            self::$_PHPCAS_DEBUG['filename'] = false;
490*d10b5556SXylle
491*d10b5556SXylle        } else {
492*d10b5556SXylle            if (empty ($filename)) {
493*d10b5556SXylle                if (preg_match('/^Win.*/', getenv('OS'))) {
494*d10b5556SXylle                    if (isset ($_ENV['TMP'])) {
495*d10b5556SXylle                        $debugDir = $_ENV['TMP'] . '/';
496*d10b5556SXylle                    } else {
497*d10b5556SXylle                        $debugDir = '';
498*d10b5556SXylle                    }
499*d10b5556SXylle                } else {
500*d10b5556SXylle                    $debugDir = DEFAULT_DEBUG_DIR;
501*d10b5556SXylle                }
502*d10b5556SXylle                $filename = $debugDir . 'phpCAS.log';
503*d10b5556SXylle            }
504*d10b5556SXylle
505*d10b5556SXylle            if (empty (self::$_PHPCAS_DEBUG['unique_id'])) {
506*d10b5556SXylle                self::$_PHPCAS_DEBUG['unique_id'] = substr(strtoupper(md5(uniqid(''))), 0, 4);
507*d10b5556SXylle            }
508*d10b5556SXylle
509*d10b5556SXylle            self::$_PHPCAS_DEBUG['filename'] = $filename;
510*d10b5556SXylle            self::$_PHPCAS_DEBUG['indent'] = 0;
511*d10b5556SXylle
512*d10b5556SXylle            phpCAS :: trace('START ('.date("Y-m-d H:i:s").') phpCAS-' . PHPCAS_VERSION . ' ******************');
513*d10b5556SXylle        }
514*d10b5556SXylle    }
515*d10b5556SXylle
516*d10b5556SXylle    /**
517*d10b5556SXylle     * Enable verbose errors messages in the website output
518*d10b5556SXylle     * This is a security relevant since internal status info may leak an may
519*d10b5556SXylle     * help an attacker. Default is therefore false
520*d10b5556SXylle     *
521*d10b5556SXylle     * @param bool $verbose enable verbose output
522*d10b5556SXylle     *
523*d10b5556SXylle     * @return void
524*d10b5556SXylle     */
525*d10b5556SXylle    public static function setVerbose($verbose)
526*d10b5556SXylle    {
527*d10b5556SXylle        if ($verbose === true) {
528*d10b5556SXylle            self::$_PHPCAS_VERBOSE = true;
529*d10b5556SXylle        } else {
530*d10b5556SXylle            self::$_PHPCAS_VERBOSE = false;
531*d10b5556SXylle        }
532*d10b5556SXylle    }
533*d10b5556SXylle
534*d10b5556SXylle
535*d10b5556SXylle    /**
536*d10b5556SXylle     * Show is verbose mode is on
537*d10b5556SXylle     *
538*d10b5556SXylle     * @return bool verbose
539*d10b5556SXylle     */
540*d10b5556SXylle    public static function getVerbose()
541*d10b5556SXylle    {
542*d10b5556SXylle        return self::$_PHPCAS_VERBOSE;
543*d10b5556SXylle    }
544*d10b5556SXylle
545*d10b5556SXylle    /**
546*d10b5556SXylle     * Logs a string in debug mode.
547*d10b5556SXylle     *
548*d10b5556SXylle     * @param string $str the string to write
549*d10b5556SXylle     *
550*d10b5556SXylle     * @return void
551*d10b5556SXylle     * @private
552*d10b5556SXylle     */
553*d10b5556SXylle    public static function log($str)
554*d10b5556SXylle    {
555*d10b5556SXylle        $indent_str = ".";
556*d10b5556SXylle
557*d10b5556SXylle
558*d10b5556SXylle        if (isset(self::$_PHPCAS_DEBUG['logger']) || !empty(self::$_PHPCAS_DEBUG['filename'])) {
559*d10b5556SXylle            for ($i = 0; $i < self::$_PHPCAS_DEBUG['indent']; $i++) {
560*d10b5556SXylle
561*d10b5556SXylle                $indent_str .= '|    ';
562*d10b5556SXylle            }
563*d10b5556SXylle            // allow for multiline output with proper identing. Usefull for
564*d10b5556SXylle            // dumping cas answers etc.
565*d10b5556SXylle            $str2 = str_replace("\n", "\n" . self::$_PHPCAS_DEBUG['unique_id'] . ' ' . $indent_str, $str);
566*d10b5556SXylle            $str3 = self::$_PHPCAS_DEBUG['unique_id'] . ' ' . $indent_str . $str2;
567*d10b5556SXylle            if (isset(self::$_PHPCAS_DEBUG['logger'])) {
568*d10b5556SXylle                self::$_PHPCAS_DEBUG['logger']->info($str3);
569*d10b5556SXylle            }
570*d10b5556SXylle            if (!empty(self::$_PHPCAS_DEBUG['filename'])) {
571*d10b5556SXylle                // Check if file exists and modifiy file permissions to be only
572*d10b5556SXylle                // readable by the webserver
573*d10b5556SXylle                if (!file_exists(self::$_PHPCAS_DEBUG['filename'])) {
574*d10b5556SXylle                    touch(self::$_PHPCAS_DEBUG['filename']);
575*d10b5556SXylle                    // Chmod will fail on windows
576*d10b5556SXylle                    @chmod(self::$_PHPCAS_DEBUG['filename'], 0600);
577*d10b5556SXylle                }
578*d10b5556SXylle                error_log($str3 . "\n", 3, self::$_PHPCAS_DEBUG['filename']);
579*d10b5556SXylle            }
580*d10b5556SXylle        }
581*d10b5556SXylle
582*d10b5556SXylle    }
583*d10b5556SXylle
584*d10b5556SXylle    /**
585*d10b5556SXylle     * This method is used by interface methods to print an error and where the
586*d10b5556SXylle     * function was originally called from.
587*d10b5556SXylle     *
588*d10b5556SXylle     * @param string $msg the message to print
589*d10b5556SXylle     *
590*d10b5556SXylle     * @return void
591*d10b5556SXylle     * @private
592*d10b5556SXylle     */
593*d10b5556SXylle    public static function error($msg)
594*d10b5556SXylle    {
595*d10b5556SXylle        phpCAS :: traceBegin();
596*d10b5556SXylle        $dbg = debug_backtrace();
597*d10b5556SXylle        $function = '?';
598*d10b5556SXylle        $file = '?';
599*d10b5556SXylle        $line = '?';
600*d10b5556SXylle        if (is_array($dbg)) {
601*d10b5556SXylle            for ($i = 1; $i < sizeof($dbg); $i++) {
602*d10b5556SXylle                if (is_array($dbg[$i]) && isset($dbg[$i]['class']) ) {
603*d10b5556SXylle                    if ($dbg[$i]['class'] == __CLASS__) {
604*d10b5556SXylle                        $function = $dbg[$i]['function'];
605*d10b5556SXylle                        $file = $dbg[$i]['file'];
606*d10b5556SXylle                        $line = $dbg[$i]['line'];
607*d10b5556SXylle                    }
608*d10b5556SXylle                }
609*d10b5556SXylle            }
610*d10b5556SXylle        }
611*d10b5556SXylle        if (self::$_PHPCAS_VERBOSE) {
612*d10b5556SXylle            echo "<br />\n<b>phpCAS error</b>: <font color=\"FF0000\"><b>" . __CLASS__ . "::" . $function . '(): ' . htmlentities($msg) . "</b></font> in <b>" . $file . "</b> on line <b>" . $line . "</b><br />\n";
613*d10b5556SXylle        }
614*d10b5556SXylle        phpCAS :: trace($msg . ' in ' . $file . 'on line ' . $line );
615*d10b5556SXylle        phpCAS :: traceEnd();
616*d10b5556SXylle
617*d10b5556SXylle        throw new CAS_GracefullTerminationException(__CLASS__ . "::" . $function . '(): ' . $msg);
618*d10b5556SXylle    }
619*d10b5556SXylle
620*d10b5556SXylle    /**
621*d10b5556SXylle     * This method is used to log something in debug mode.
622*d10b5556SXylle     *
623*d10b5556SXylle     * @param string $str string to log
624*d10b5556SXylle     *
625*d10b5556SXylle     * @return void
626*d10b5556SXylle     */
627*d10b5556SXylle    public static function trace($str)
628*d10b5556SXylle    {
629*d10b5556SXylle        $dbg = debug_backtrace();
630*d10b5556SXylle        phpCAS :: log($str . ' [' . basename($dbg[0]['file']) . ':' . $dbg[0]['line'] . ']');
631*d10b5556SXylle    }
632*d10b5556SXylle
633*d10b5556SXylle    /**
634*d10b5556SXylle     * This method is used to indicate the start of the execution of a function
635*d10b5556SXylle     * in debug mode.
636*d10b5556SXylle     *
637*d10b5556SXylle     * @return void
638*d10b5556SXylle     */
639*d10b5556SXylle    public static function traceBegin()
640*d10b5556SXylle    {
641*d10b5556SXylle        $dbg = debug_backtrace();
642*d10b5556SXylle        $str = '=> ';
643*d10b5556SXylle        if (!empty ($dbg[1]['class'])) {
644*d10b5556SXylle            $str .= $dbg[1]['class'] . '::';
645*d10b5556SXylle        }
646*d10b5556SXylle        $str .= $dbg[1]['function'] . '(';
647*d10b5556SXylle        if (is_array($dbg[1]['args'])) {
648*d10b5556SXylle            foreach ($dbg[1]['args'] as $index => $arg) {
649*d10b5556SXylle                if ($index != 0) {
650*d10b5556SXylle                    $str .= ', ';
651*d10b5556SXylle                }
652*d10b5556SXylle                if (is_object($arg)) {
653*d10b5556SXylle                    $str .= get_class($arg);
654*d10b5556SXylle                } else {
655*d10b5556SXylle                    $str .= str_replace(array("\r\n", "\n", "\r"), "", var_export($arg, true));
656*d10b5556SXylle                }
657*d10b5556SXylle            }
658*d10b5556SXylle        }
659*d10b5556SXylle        if (isset($dbg[1]['file'])) {
660*d10b5556SXylle            $file = basename($dbg[1]['file']);
661*d10b5556SXylle        } else {
662*d10b5556SXylle            $file = 'unknown_file';
663*d10b5556SXylle        }
664*d10b5556SXylle        if (isset($dbg[1]['line'])) {
665*d10b5556SXylle            $line = $dbg[1]['line'];
666*d10b5556SXylle        } else {
667*d10b5556SXylle            $line = 'unknown_line';
668*d10b5556SXylle        }
669*d10b5556SXylle        $str .= ') [' . $file . ':' . $line . ']';
670*d10b5556SXylle        phpCAS :: log($str);
671*d10b5556SXylle        if (!isset(self::$_PHPCAS_DEBUG['indent'])) {
672*d10b5556SXylle            self::$_PHPCAS_DEBUG['indent'] = 0;
673*d10b5556SXylle        } else {
674*d10b5556SXylle            self::$_PHPCAS_DEBUG['indent']++;
675*d10b5556SXylle        }
676*d10b5556SXylle    }
677*d10b5556SXylle
678*d10b5556SXylle    /**
679*d10b5556SXylle     * This method is used to indicate the end of the execution of a function in
680*d10b5556SXylle     * debug mode.
681*d10b5556SXylle     *
682*d10b5556SXylle     * @param mixed $res the result of the function
683*d10b5556SXylle     *
684*d10b5556SXylle     * @return void
685*d10b5556SXylle     */
686*d10b5556SXylle    public static function traceEnd($res = '')
687*d10b5556SXylle    {
688*d10b5556SXylle        if (empty(self::$_PHPCAS_DEBUG['indent'])) {
689*d10b5556SXylle            self::$_PHPCAS_DEBUG['indent'] = 0;
690*d10b5556SXylle        } else {
691*d10b5556SXylle            self::$_PHPCAS_DEBUG['indent']--;
692*d10b5556SXylle        }
693*d10b5556SXylle        $str = '';
694*d10b5556SXylle        if (is_object($res)) {
695*d10b5556SXylle            $str .= '<= ' . get_class($res);
696*d10b5556SXylle        } else {
697*d10b5556SXylle            $str .= '<= ' . str_replace(array("\r\n", "\n", "\r"), "", var_export($res, true));
698*d10b5556SXylle        }
699*d10b5556SXylle
700*d10b5556SXylle        phpCAS :: log($str);
701*d10b5556SXylle    }
702*d10b5556SXylle
703*d10b5556SXylle    /**
704*d10b5556SXylle     * This method is used to indicate the end of the execution of the program
705*d10b5556SXylle     *
706*d10b5556SXylle     * @return void
707*d10b5556SXylle     */
708*d10b5556SXylle    public static function traceExit()
709*d10b5556SXylle    {
710*d10b5556SXylle        phpCAS :: log('exit()');
711*d10b5556SXylle        while (self::$_PHPCAS_DEBUG['indent'] > 0) {
712*d10b5556SXylle            phpCAS :: log('-');
713*d10b5556SXylle            self::$_PHPCAS_DEBUG['indent']--;
714*d10b5556SXylle        }
715*d10b5556SXylle    }
716*d10b5556SXylle
717*d10b5556SXylle    /** @} */
718*d10b5556SXylle    // ########################################################################
719*d10b5556SXylle    //  INTERNATIONALIZATION
720*d10b5556SXylle    // ########################################################################
721*d10b5556SXylle    /**
722*d10b5556SXylle    * @addtogroup publicLang
723*d10b5556SXylle    * @{
724*d10b5556SXylle    */
725*d10b5556SXylle
726*d10b5556SXylle    /**
727*d10b5556SXylle     * This method is used to set the language used by phpCAS.
728*d10b5556SXylle     *
729*d10b5556SXylle     * @param string $lang string representing the language.
730*d10b5556SXylle     *
731*d10b5556SXylle     * @return void
732*d10b5556SXylle     *
733*d10b5556SXylle     * @sa PHPCAS_LANG_FRENCH, PHPCAS_LANG_ENGLISH
734*d10b5556SXylle     * @note Can be called only once.
735*d10b5556SXylle     */
736*d10b5556SXylle    public static function setLang($lang)
737*d10b5556SXylle    {
738*d10b5556SXylle        phpCAS::_validateClientExists();
739*d10b5556SXylle
740*d10b5556SXylle        try {
741*d10b5556SXylle            self::$_PHPCAS_CLIENT->setLang($lang);
742*d10b5556SXylle        } catch (Exception $e) {
743*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
744*d10b5556SXylle        }
745*d10b5556SXylle    }
746*d10b5556SXylle
747*d10b5556SXylle    /** @} */
748*d10b5556SXylle    // ########################################################################
749*d10b5556SXylle    //  VERSION
750*d10b5556SXylle    // ########################################################################
751*d10b5556SXylle    /**
752*d10b5556SXylle    * @addtogroup public
753*d10b5556SXylle    * @{
754*d10b5556SXylle    */
755*d10b5556SXylle
756*d10b5556SXylle    /**
757*d10b5556SXylle     * This method returns the phpCAS version.
758*d10b5556SXylle     *
759*d10b5556SXylle     * @return string the phpCAS version.
760*d10b5556SXylle     */
761*d10b5556SXylle    public static function getVersion()
762*d10b5556SXylle    {
763*d10b5556SXylle        return PHPCAS_VERSION;
764*d10b5556SXylle    }
765*d10b5556SXylle
766*d10b5556SXylle    /**
767*d10b5556SXylle     * This method returns supported protocols.
768*d10b5556SXylle     *
769*d10b5556SXylle     * @return array an array of all supported protocols. Use internal protocol name as array key.
770*d10b5556SXylle     */
771*d10b5556SXylle    public static function getSupportedProtocols()
772*d10b5556SXylle    {
773*d10b5556SXylle        $supportedProtocols = array();
774*d10b5556SXylle        $supportedProtocols[CAS_VERSION_1_0] = 'CAS 1.0';
775*d10b5556SXylle        $supportedProtocols[CAS_VERSION_2_0] = 'CAS 2.0';
776*d10b5556SXylle        $supportedProtocols[CAS_VERSION_3_0] = 'CAS 3.0';
777*d10b5556SXylle        $supportedProtocols[SAML_VERSION_1_1] = 'SAML 1.1';
778*d10b5556SXylle
779*d10b5556SXylle        return $supportedProtocols;
780*d10b5556SXylle    }
781*d10b5556SXylle
782*d10b5556SXylle    /** @} */
783*d10b5556SXylle    // ########################################################################
784*d10b5556SXylle    //  HTML OUTPUT
785*d10b5556SXylle    // ########################################################################
786*d10b5556SXylle    /**
787*d10b5556SXylle    * @addtogroup publicOutput
788*d10b5556SXylle    * @{
789*d10b5556SXylle    */
790*d10b5556SXylle
791*d10b5556SXylle    /**
792*d10b5556SXylle     * This method sets the HTML header used for all outputs.
793*d10b5556SXylle     *
794*d10b5556SXylle     * @param string $header the HTML header.
795*d10b5556SXylle     *
796*d10b5556SXylle     * @return void
797*d10b5556SXylle     */
798*d10b5556SXylle    public static function setHTMLHeader($header)
799*d10b5556SXylle    {
800*d10b5556SXylle        phpCAS::_validateClientExists();
801*d10b5556SXylle
802*d10b5556SXylle        try {
803*d10b5556SXylle            self::$_PHPCAS_CLIENT->setHTMLHeader($header);
804*d10b5556SXylle        } catch (Exception $e) {
805*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
806*d10b5556SXylle        }
807*d10b5556SXylle    }
808*d10b5556SXylle
809*d10b5556SXylle    /**
810*d10b5556SXylle     * This method sets the HTML footer used for all outputs.
811*d10b5556SXylle     *
812*d10b5556SXylle     * @param string $footer the HTML footer.
813*d10b5556SXylle     *
814*d10b5556SXylle     * @return void
815*d10b5556SXylle     */
816*d10b5556SXylle    public static function setHTMLFooter($footer)
817*d10b5556SXylle    {
818*d10b5556SXylle        phpCAS::_validateClientExists();
819*d10b5556SXylle
820*d10b5556SXylle        try {
821*d10b5556SXylle            self::$_PHPCAS_CLIENT->setHTMLFooter($footer);
822*d10b5556SXylle        } catch (Exception $e) {
823*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
824*d10b5556SXylle        }
825*d10b5556SXylle    }
826*d10b5556SXylle
827*d10b5556SXylle    /** @} */
828*d10b5556SXylle    // ########################################################################
829*d10b5556SXylle    //  PGT STORAGE
830*d10b5556SXylle    // ########################################################################
831*d10b5556SXylle    /**
832*d10b5556SXylle    * @addtogroup publicPGTStorage
833*d10b5556SXylle    * @{
834*d10b5556SXylle    */
835*d10b5556SXylle
836*d10b5556SXylle    /**
837*d10b5556SXylle     * This method can be used to set a custom PGT storage object.
838*d10b5556SXylle     *
839*d10b5556SXylle     * @param CAS_PGTStorage_AbstractStorage $storage a PGT storage object that inherits from the
840*d10b5556SXylle     * CAS_PGTStorage_AbstractStorage class
841*d10b5556SXylle     *
842*d10b5556SXylle     * @return void
843*d10b5556SXylle     */
844*d10b5556SXylle    public static function setPGTStorage($storage)
845*d10b5556SXylle    {
846*d10b5556SXylle        phpCAS :: traceBegin();
847*d10b5556SXylle        phpCAS::_validateProxyExists();
848*d10b5556SXylle
849*d10b5556SXylle        try {
850*d10b5556SXylle            self::$_PHPCAS_CLIENT->setPGTStorage($storage);
851*d10b5556SXylle        } catch (Exception $e) {
852*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
853*d10b5556SXylle        }
854*d10b5556SXylle        phpCAS :: traceEnd();
855*d10b5556SXylle    }
856*d10b5556SXylle
857*d10b5556SXylle    /**
858*d10b5556SXylle     * This method is used to tell phpCAS to store the response of the
859*d10b5556SXylle     * CAS server to PGT requests in a database.
860*d10b5556SXylle     *
861*d10b5556SXylle     * @param string $dsn_or_pdo     a dsn string to use for creating a PDO
862*d10b5556SXylle     * object or a PDO object
863*d10b5556SXylle     * @param string $username       the username to use when connecting to the
864*d10b5556SXylle     * database
865*d10b5556SXylle     * @param string $password       the password to use when connecting to the
866*d10b5556SXylle     * database
867*d10b5556SXylle     * @param string $table          the table to use for storing and retrieving
868*d10b5556SXylle     * PGT's
869*d10b5556SXylle     * @param string $driver_options any driver options to use when connecting
870*d10b5556SXylle     * to the database
871*d10b5556SXylle     *
872*d10b5556SXylle     * @return void
873*d10b5556SXylle     */
874*d10b5556SXylle    public static function setPGTStorageDb($dsn_or_pdo, $username='',
875*d10b5556SXylle        $password='', $table='', $driver_options=null
876*d10b5556SXylle    ) {
877*d10b5556SXylle        phpCAS :: traceBegin();
878*d10b5556SXylle        phpCAS::_validateProxyExists();
879*d10b5556SXylle
880*d10b5556SXylle        try {
881*d10b5556SXylle            self::$_PHPCAS_CLIENT->setPGTStorageDb($dsn_or_pdo, $username, $password, $table, $driver_options);
882*d10b5556SXylle        } catch (Exception $e) {
883*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
884*d10b5556SXylle        }
885*d10b5556SXylle        phpCAS :: traceEnd();
886*d10b5556SXylle    }
887*d10b5556SXylle
888*d10b5556SXylle    /**
889*d10b5556SXylle     * This method is used to tell phpCAS to store the response of the
890*d10b5556SXylle     * CAS server to PGT requests onto the filesystem.
891*d10b5556SXylle     *
892*d10b5556SXylle     * @param string $path the path where the PGT's should be stored
893*d10b5556SXylle     *
894*d10b5556SXylle     * @return void
895*d10b5556SXylle     */
896*d10b5556SXylle    public static function setPGTStorageFile($path = '')
897*d10b5556SXylle    {
898*d10b5556SXylle        phpCAS :: traceBegin();
899*d10b5556SXylle        phpCAS::_validateProxyExists();
900*d10b5556SXylle
901*d10b5556SXylle        try {
902*d10b5556SXylle            self::$_PHPCAS_CLIENT->setPGTStorageFile($path);
903*d10b5556SXylle        } catch (Exception $e) {
904*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
905*d10b5556SXylle        }
906*d10b5556SXylle        phpCAS :: traceEnd();
907*d10b5556SXylle    }
908*d10b5556SXylle    /** @} */
909*d10b5556SXylle    // ########################################################################
910*d10b5556SXylle    // ACCESS TO EXTERNAL SERVICES
911*d10b5556SXylle    // ########################################################################
912*d10b5556SXylle    /**
913*d10b5556SXylle    * @addtogroup publicServices
914*d10b5556SXylle    * @{
915*d10b5556SXylle    */
916*d10b5556SXylle
917*d10b5556SXylle    /**
918*d10b5556SXylle     * Answer a proxy-authenticated service handler.
919*d10b5556SXylle     *
920*d10b5556SXylle     * @param string $type The service type. One of
921*d10b5556SXylle     * PHPCAS_PROXIED_SERVICE_HTTP_GET; PHPCAS_PROXIED_SERVICE_HTTP_POST;
922*d10b5556SXylle     * PHPCAS_PROXIED_SERVICE_IMAP
923*d10b5556SXylle     *
924*d10b5556SXylle     * @return CAS_ProxiedService
925*d10b5556SXylle     * @throws InvalidArgumentException If the service type is unknown.
926*d10b5556SXylle     */
927*d10b5556SXylle    public static function getProxiedService ($type)
928*d10b5556SXylle    {
929*d10b5556SXylle        phpCAS :: traceBegin();
930*d10b5556SXylle        phpCAS::_validateProxyExists();
931*d10b5556SXylle
932*d10b5556SXylle        try {
933*d10b5556SXylle            $res = self::$_PHPCAS_CLIENT->getProxiedService($type);
934*d10b5556SXylle        } catch (Exception $e) {
935*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
936*d10b5556SXylle        }
937*d10b5556SXylle
938*d10b5556SXylle        phpCAS :: traceEnd();
939*d10b5556SXylle        return $res;
940*d10b5556SXylle    }
941*d10b5556SXylle
942*d10b5556SXylle    /**
943*d10b5556SXylle     * Initialize a proxied-service handler with the proxy-ticket it should use.
944*d10b5556SXylle     *
945*d10b5556SXylle     * @param CAS_ProxiedService $proxiedService Proxied Service Handler
946*d10b5556SXylle     *
947*d10b5556SXylle     * @return void
948*d10b5556SXylle     * @throws CAS_ProxyTicketException If there is a proxy-ticket failure.
949*d10b5556SXylle     *		The code of the Exception will be one of:
950*d10b5556SXylle     *			PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE
951*d10b5556SXylle     *			PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE
952*d10b5556SXylle     *			PHPCAS_SERVICE_PT_FAILURE
953*d10b5556SXylle     */
954*d10b5556SXylle    public static function initializeProxiedService (CAS_ProxiedService $proxiedService)
955*d10b5556SXylle    {
956*d10b5556SXylle        phpCAS::_validateProxyExists();
957*d10b5556SXylle
958*d10b5556SXylle        try {
959*d10b5556SXylle            self::$_PHPCAS_CLIENT->initializeProxiedService($proxiedService);
960*d10b5556SXylle        } catch (Exception $e) {
961*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
962*d10b5556SXylle        }
963*d10b5556SXylle    }
964*d10b5556SXylle
965*d10b5556SXylle    /**
966*d10b5556SXylle     * This method is used to access an HTTP[S] service.
967*d10b5556SXylle     *
968*d10b5556SXylle     * @param string $url       the service to access.
969*d10b5556SXylle     * @param int &$err_code an error code Possible values are
970*d10b5556SXylle     * PHPCAS_SERVICE_OK (on success), PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE,
971*d10b5556SXylle     * PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE, PHPCAS_SERVICE_PT_FAILURE,
972*d10b5556SXylle     * PHPCAS_SERVICE_NOT_AVAILABLE.
973*d10b5556SXylle     * @param string &$output   the output of the service (also used to give an
974*d10b5556SXylle     * error message on failure).
975*d10b5556SXylle     *
976*d10b5556SXylle     * @return bool true on success, false otherwise (in this later case,
977*d10b5556SXylle     * $err_code gives the reason why it failed and $output contains an error
978*d10b5556SXylle     * message).
979*d10b5556SXylle     */
980*d10b5556SXylle    public static function serviceWeb($url, & $err_code, & $output)
981*d10b5556SXylle    {
982*d10b5556SXylle        phpCAS :: traceBegin();
983*d10b5556SXylle        phpCAS::_validateProxyExists();
984*d10b5556SXylle
985*d10b5556SXylle        try {
986*d10b5556SXylle            $res = self::$_PHPCAS_CLIENT->serviceWeb($url, $err_code, $output);
987*d10b5556SXylle        } catch (Exception $e) {
988*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
989*d10b5556SXylle        }
990*d10b5556SXylle
991*d10b5556SXylle        phpCAS :: traceEnd($res);
992*d10b5556SXylle        return $res;
993*d10b5556SXylle    }
994*d10b5556SXylle
995*d10b5556SXylle    /**
996*d10b5556SXylle     * This method is used to access an IMAP/POP3/NNTP service.
997*d10b5556SXylle     *
998*d10b5556SXylle     * @param string $url       a string giving the URL of the service,
999*d10b5556SXylle     * including the mailing box for IMAP URLs, as accepted by imap_open().
1000*d10b5556SXylle     * @param string $service   a string giving for CAS retrieve Proxy ticket
1001*d10b5556SXylle     * @param string $flags     options given to imap_open().
1002*d10b5556SXylle     * @param int &$err_code an error code Possible values are
1003*d10b5556SXylle     * PHPCAS_SERVICE_OK (on success), PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE,
1004*d10b5556SXylle     * PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE, PHPCAS_SERVICE_PT_FAILURE,
1005*d10b5556SXylle     * PHPCAS_SERVICE_NOT_AVAILABLE.
1006*d10b5556SXylle     * @param string &$err_msg  an error message on failure
1007*d10b5556SXylle     * @param string &$pt       the Proxy Ticket (PT) retrieved from the CAS
1008*d10b5556SXylle     * server to access the URL on success, false on error).
1009*d10b5556SXylle     *
1010*d10b5556SXylle     * @return object|false IMAP stream on success, false otherwise (in this later
1011*d10b5556SXylle     * case, $err_code gives the reason why it failed and $err_msg contains an
1012*d10b5556SXylle     * error message).
1013*d10b5556SXylle     */
1014*d10b5556SXylle    public static function serviceMail($url, $service, $flags, & $err_code, & $err_msg, & $pt)
1015*d10b5556SXylle    {
1016*d10b5556SXylle        phpCAS :: traceBegin();
1017*d10b5556SXylle        phpCAS::_validateProxyExists();
1018*d10b5556SXylle
1019*d10b5556SXylle        try {
1020*d10b5556SXylle            $res = self::$_PHPCAS_CLIENT->serviceMail($url, $service, $flags, $err_code, $err_msg, $pt);
1021*d10b5556SXylle        } catch (Exception $e) {
1022*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
1023*d10b5556SXylle        }
1024*d10b5556SXylle
1025*d10b5556SXylle        phpCAS :: traceEnd($res);
1026*d10b5556SXylle        return $res;
1027*d10b5556SXylle    }
1028*d10b5556SXylle
1029*d10b5556SXylle    /** @} */
1030*d10b5556SXylle    // ########################################################################
1031*d10b5556SXylle    //  AUTHENTICATION
1032*d10b5556SXylle    // ########################################################################
1033*d10b5556SXylle    /**
1034*d10b5556SXylle    * @addtogroup publicAuth
1035*d10b5556SXylle    * @{
1036*d10b5556SXylle    */
1037*d10b5556SXylle
1038*d10b5556SXylle    /**
1039*d10b5556SXylle     * Set the times authentication will be cached before really accessing the
1040*d10b5556SXylle     * CAS server in gateway mode:
1041*d10b5556SXylle     * - -1: check only once, and then never again (until you pree login)
1042*d10b5556SXylle     * - 0: always check
1043*d10b5556SXylle     * - n: check every "n" time
1044*d10b5556SXylle     *
1045*d10b5556SXylle     * @param int $n an integer.
1046*d10b5556SXylle     *
1047*d10b5556SXylle     * @return void
1048*d10b5556SXylle     */
1049*d10b5556SXylle    public static function setCacheTimesForAuthRecheck($n)
1050*d10b5556SXylle    {
1051*d10b5556SXylle        phpCAS::_validateClientExists();
1052*d10b5556SXylle
1053*d10b5556SXylle        try {
1054*d10b5556SXylle            self::$_PHPCAS_CLIENT->setCacheTimesForAuthRecheck($n);
1055*d10b5556SXylle        } catch (Exception $e) {
1056*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
1057*d10b5556SXylle        }
1058*d10b5556SXylle    }
1059*d10b5556SXylle
1060*d10b5556SXylle
1061*d10b5556SXylle    /**
1062*d10b5556SXylle     * Set a callback function to be run when receiving CAS attributes
1063*d10b5556SXylle     *
1064*d10b5556SXylle     * The callback function will be passed an $success_elements
1065*d10b5556SXylle     * payload of the response (\DOMElement) as its first parameter.
1066*d10b5556SXylle     *
1067*d10b5556SXylle     * @param string $function       Callback function
1068*d10b5556SXylle     * @param array  $additionalArgs optional array of arguments
1069*d10b5556SXylle     *
1070*d10b5556SXylle     * @return void
1071*d10b5556SXylle     */
1072*d10b5556SXylle    public static function setCasAttributeParserCallback($function, array $additionalArgs = array())
1073*d10b5556SXylle    {
1074*d10b5556SXylle        phpCAS::_validateClientExists();
1075*d10b5556SXylle
1076*d10b5556SXylle        self::$_PHPCAS_CLIENT->setCasAttributeParserCallback($function, $additionalArgs);
1077*d10b5556SXylle    }
1078*d10b5556SXylle
1079*d10b5556SXylle    /**
1080*d10b5556SXylle     * Set a callback function to be run when a user authenticates.
1081*d10b5556SXylle     *
1082*d10b5556SXylle     * The callback function will be passed a $logoutTicket as its first
1083*d10b5556SXylle     * parameter, followed by any $additionalArgs you pass. The $logoutTicket
1084*d10b5556SXylle     * parameter is an opaque string that can be used to map the session-id to
1085*d10b5556SXylle     * logout request in order to support single-signout in applications that
1086*d10b5556SXylle     * manage their own sessions (rather than letting phpCAS start the session).
1087*d10b5556SXylle     *
1088*d10b5556SXylle     * phpCAS::forceAuthentication() will always exit and forward client unless
1089*d10b5556SXylle     * they are already authenticated. To perform an action at the moment the user
1090*d10b5556SXylle     * logs in (such as registering an account, performing logging, etc), register
1091*d10b5556SXylle     * a callback function here.
1092*d10b5556SXylle     *
1093*d10b5556SXylle     * @param callable $function       Callback function
1094*d10b5556SXylle     * @param array  $additionalArgs optional array of arguments
1095*d10b5556SXylle     *
1096*d10b5556SXylle     * @return void
1097*d10b5556SXylle     */
1098*d10b5556SXylle    public static function setPostAuthenticateCallback ($function, array $additionalArgs = array())
1099*d10b5556SXylle    {
1100*d10b5556SXylle        phpCAS::_validateClientExists();
1101*d10b5556SXylle
1102*d10b5556SXylle        self::$_PHPCAS_CLIENT->setPostAuthenticateCallback($function, $additionalArgs);
1103*d10b5556SXylle    }
1104*d10b5556SXylle
1105*d10b5556SXylle    /**
1106*d10b5556SXylle     * Set a callback function to be run when a single-signout request is
1107*d10b5556SXylle     * received. The callback function will be passed a $logoutTicket as its
1108*d10b5556SXylle     * first parameter, followed by any $additionalArgs you pass. The
1109*d10b5556SXylle     * $logoutTicket parameter is an opaque string that can be used to map a
1110*d10b5556SXylle     * session-id to the logout request in order to support single-signout in
1111*d10b5556SXylle     * applications that manage their own sessions (rather than letting phpCAS
1112*d10b5556SXylle     * start and destroy the session).
1113*d10b5556SXylle     *
1114*d10b5556SXylle     * @param callable $function       Callback function
1115*d10b5556SXylle     * @param array  $additionalArgs optional array of arguments
1116*d10b5556SXylle     *
1117*d10b5556SXylle     * @return void
1118*d10b5556SXylle     */
1119*d10b5556SXylle    public static function setSingleSignoutCallback ($function, array $additionalArgs = array())
1120*d10b5556SXylle    {
1121*d10b5556SXylle        phpCAS::_validateClientExists();
1122*d10b5556SXylle
1123*d10b5556SXylle        self::$_PHPCAS_CLIENT->setSingleSignoutCallback($function, $additionalArgs);
1124*d10b5556SXylle    }
1125*d10b5556SXylle
1126*d10b5556SXylle    /**
1127*d10b5556SXylle     * This method is called to check if the user is already authenticated
1128*d10b5556SXylle     * locally or has a global cas session. A already existing cas session is
1129*d10b5556SXylle     * determined by a cas gateway call.(cas login call without any interactive
1130*d10b5556SXylle     * prompt)
1131*d10b5556SXylle     *
1132*d10b5556SXylle     * @return bool true when the user is authenticated, false when a previous
1133*d10b5556SXylle     * gateway login failed or the function will not return if the user is
1134*d10b5556SXylle     * redirected to the cas server for a gateway login attempt
1135*d10b5556SXylle     */
1136*d10b5556SXylle    public static function checkAuthentication()
1137*d10b5556SXylle    {
1138*d10b5556SXylle        phpCAS :: traceBegin();
1139*d10b5556SXylle        phpCAS::_validateClientExists();
1140*d10b5556SXylle
1141*d10b5556SXylle        $auth = self::$_PHPCAS_CLIENT->checkAuthentication();
1142*d10b5556SXylle
1143*d10b5556SXylle        // store where the authentication has been checked and the result
1144*d10b5556SXylle        self::$_PHPCAS_CLIENT->markAuthenticationCall($auth);
1145*d10b5556SXylle
1146*d10b5556SXylle        phpCAS :: traceEnd($auth);
1147*d10b5556SXylle        return $auth;
1148*d10b5556SXylle    }
1149*d10b5556SXylle
1150*d10b5556SXylle    /**
1151*d10b5556SXylle     * This method is called to force authentication if the user was not already
1152*d10b5556SXylle     * authenticated. If the user is not authenticated, halt by redirecting to
1153*d10b5556SXylle     * the CAS server.
1154*d10b5556SXylle     *
1155*d10b5556SXylle     * @return bool Authentication
1156*d10b5556SXylle     */
1157*d10b5556SXylle    public static function forceAuthentication()
1158*d10b5556SXylle    {
1159*d10b5556SXylle        phpCAS :: traceBegin();
1160*d10b5556SXylle        phpCAS::_validateClientExists();
1161*d10b5556SXylle        $auth = self::$_PHPCAS_CLIENT->forceAuthentication();
1162*d10b5556SXylle
1163*d10b5556SXylle        // store where the authentication has been checked and the result
1164*d10b5556SXylle        self::$_PHPCAS_CLIENT->markAuthenticationCall($auth);
1165*d10b5556SXylle
1166*d10b5556SXylle        /*      if (!$auth) {
1167*d10b5556SXylle         phpCAS :: trace('user is not authenticated, redirecting to the CAS server');
1168*d10b5556SXylle        self::$_PHPCAS_CLIENT->forceAuthentication();
1169*d10b5556SXylle        } else {
1170*d10b5556SXylle        phpCAS :: trace('no need to authenticate (user `' . phpCAS :: getUser() . '\' is already authenticated)');
1171*d10b5556SXylle        }*/
1172*d10b5556SXylle
1173*d10b5556SXylle        phpCAS :: traceEnd();
1174*d10b5556SXylle        return $auth;
1175*d10b5556SXylle    }
1176*d10b5556SXylle
1177*d10b5556SXylle    /**
1178*d10b5556SXylle     * This method is called to renew the authentication.
1179*d10b5556SXylle     *
1180*d10b5556SXylle     * @return void
1181*d10b5556SXylle     **/
1182*d10b5556SXylle    public static function renewAuthentication()
1183*d10b5556SXylle    {
1184*d10b5556SXylle        phpCAS :: traceBegin();
1185*d10b5556SXylle        phpCAS::_validateClientExists();
1186*d10b5556SXylle
1187*d10b5556SXylle        $auth = self::$_PHPCAS_CLIENT->renewAuthentication();
1188*d10b5556SXylle
1189*d10b5556SXylle        // store where the authentication has been checked and the result
1190*d10b5556SXylle        self::$_PHPCAS_CLIENT->markAuthenticationCall($auth);
1191*d10b5556SXylle
1192*d10b5556SXylle        //self::$_PHPCAS_CLIENT->renewAuthentication();
1193*d10b5556SXylle        phpCAS :: traceEnd();
1194*d10b5556SXylle    }
1195*d10b5556SXylle
1196*d10b5556SXylle    /**
1197*d10b5556SXylle     * This method is called to check if the user is authenticated (previously or by
1198*d10b5556SXylle     * tickets given in the URL).
1199*d10b5556SXylle     *
1200*d10b5556SXylle     * @return bool true when the user is authenticated.
1201*d10b5556SXylle     */
1202*d10b5556SXylle    public static function isAuthenticated()
1203*d10b5556SXylle    {
1204*d10b5556SXylle        phpCAS :: traceBegin();
1205*d10b5556SXylle        phpCAS::_validateClientExists();
1206*d10b5556SXylle
1207*d10b5556SXylle        // call the isAuthenticated method of the $_PHPCAS_CLIENT object
1208*d10b5556SXylle        $auth = self::$_PHPCAS_CLIENT->isAuthenticated();
1209*d10b5556SXylle
1210*d10b5556SXylle        // store where the authentication has been checked and the result
1211*d10b5556SXylle        self::$_PHPCAS_CLIENT->markAuthenticationCall($auth);
1212*d10b5556SXylle
1213*d10b5556SXylle        phpCAS :: traceEnd($auth);
1214*d10b5556SXylle        return $auth;
1215*d10b5556SXylle    }
1216*d10b5556SXylle
1217*d10b5556SXylle    /**
1218*d10b5556SXylle     * Checks whether authenticated based on $_SESSION. Useful to avoid
1219*d10b5556SXylle     * server calls.
1220*d10b5556SXylle     *
1221*d10b5556SXylle     * @return bool true if authenticated, false otherwise.
1222*d10b5556SXylle     * @since 0.4.22 by Brendan Arnold
1223*d10b5556SXylle     */
1224*d10b5556SXylle    public static function isSessionAuthenticated()
1225*d10b5556SXylle    {
1226*d10b5556SXylle        phpCAS::_validateClientExists();
1227*d10b5556SXylle
1228*d10b5556SXylle        return (self::$_PHPCAS_CLIENT->isSessionAuthenticated());
1229*d10b5556SXylle    }
1230*d10b5556SXylle
1231*d10b5556SXylle    /**
1232*d10b5556SXylle     * This method returns the CAS user's login name.
1233*d10b5556SXylle     *
1234*d10b5556SXylle     * @return string the login name of the authenticated user
1235*d10b5556SXylle     * @warning should only be called after phpCAS::forceAuthentication()
1236*d10b5556SXylle     * or phpCAS::checkAuthentication().
1237*d10b5556SXylle     * */
1238*d10b5556SXylle    public static function getUser()
1239*d10b5556SXylle    {
1240*d10b5556SXylle        phpCAS::_validateClientExists();
1241*d10b5556SXylle
1242*d10b5556SXylle        try {
1243*d10b5556SXylle            return self::$_PHPCAS_CLIENT->getUser();
1244*d10b5556SXylle        } catch (Exception $e) {
1245*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
1246*d10b5556SXylle        }
1247*d10b5556SXylle    }
1248*d10b5556SXylle
1249*d10b5556SXylle    /**
1250*d10b5556SXylle     * Answer attributes about the authenticated user.
1251*d10b5556SXylle     *
1252*d10b5556SXylle     * @warning should only be called after phpCAS::forceAuthentication()
1253*d10b5556SXylle     * or phpCAS::checkAuthentication().
1254*d10b5556SXylle     *
1255*d10b5556SXylle     * @return array
1256*d10b5556SXylle     */
1257*d10b5556SXylle    public static function getAttributes()
1258*d10b5556SXylle    {
1259*d10b5556SXylle        phpCAS::_validateClientExists();
1260*d10b5556SXylle
1261*d10b5556SXylle        try {
1262*d10b5556SXylle            return self::$_PHPCAS_CLIENT->getAttributes();
1263*d10b5556SXylle        } catch (Exception $e) {
1264*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
1265*d10b5556SXylle        }
1266*d10b5556SXylle    }
1267*d10b5556SXylle
1268*d10b5556SXylle    /**
1269*d10b5556SXylle     * Answer true if there are attributes for the authenticated user.
1270*d10b5556SXylle     *
1271*d10b5556SXylle     * @warning should only be called after phpCAS::forceAuthentication()
1272*d10b5556SXylle     * or phpCAS::checkAuthentication().
1273*d10b5556SXylle     *
1274*d10b5556SXylle     * @return bool
1275*d10b5556SXylle     */
1276*d10b5556SXylle    public static function hasAttributes()
1277*d10b5556SXylle    {
1278*d10b5556SXylle        phpCAS::_validateClientExists();
1279*d10b5556SXylle
1280*d10b5556SXylle        try {
1281*d10b5556SXylle            return self::$_PHPCAS_CLIENT->hasAttributes();
1282*d10b5556SXylle        } catch (Exception $e) {
1283*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
1284*d10b5556SXylle        }
1285*d10b5556SXylle    }
1286*d10b5556SXylle
1287*d10b5556SXylle    /**
1288*d10b5556SXylle     * Answer true if an attribute exists for the authenticated user.
1289*d10b5556SXylle     *
1290*d10b5556SXylle     * @param string $key attribute name
1291*d10b5556SXylle     *
1292*d10b5556SXylle     * @return bool
1293*d10b5556SXylle     * @warning should only be called after phpCAS::forceAuthentication()
1294*d10b5556SXylle     * or phpCAS::checkAuthentication().
1295*d10b5556SXylle     */
1296*d10b5556SXylle    public static function hasAttribute($key)
1297*d10b5556SXylle    {
1298*d10b5556SXylle        phpCAS::_validateClientExists();
1299*d10b5556SXylle
1300*d10b5556SXylle        try {
1301*d10b5556SXylle            return self::$_PHPCAS_CLIENT->hasAttribute($key);
1302*d10b5556SXylle        } catch (Exception $e) {
1303*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
1304*d10b5556SXylle        }
1305*d10b5556SXylle    }
1306*d10b5556SXylle
1307*d10b5556SXylle    /**
1308*d10b5556SXylle     * Answer an attribute for the authenticated user.
1309*d10b5556SXylle     *
1310*d10b5556SXylle     * @param string $key attribute name
1311*d10b5556SXylle     *
1312*d10b5556SXylle     * @return mixed string for a single value or an array if multiple values exist.
1313*d10b5556SXylle     * @warning should only be called after phpCAS::forceAuthentication()
1314*d10b5556SXylle     * or phpCAS::checkAuthentication().
1315*d10b5556SXylle     */
1316*d10b5556SXylle    public static function getAttribute($key)
1317*d10b5556SXylle    {
1318*d10b5556SXylle        phpCAS::_validateClientExists();
1319*d10b5556SXylle
1320*d10b5556SXylle        try {
1321*d10b5556SXylle            return self::$_PHPCAS_CLIENT->getAttribute($key);
1322*d10b5556SXylle        } catch (Exception $e) {
1323*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
1324*d10b5556SXylle        }
1325*d10b5556SXylle    }
1326*d10b5556SXylle
1327*d10b5556SXylle    /**
1328*d10b5556SXylle     * Handle logout requests.
1329*d10b5556SXylle     *
1330*d10b5556SXylle     * @param bool  $check_client    additional safety check
1331*d10b5556SXylle     * @param array $allowed_clients array of allowed clients
1332*d10b5556SXylle     *
1333*d10b5556SXylle     * @return void
1334*d10b5556SXylle     */
1335*d10b5556SXylle    public static function handleLogoutRequests($check_client = true, $allowed_clients = array())
1336*d10b5556SXylle    {
1337*d10b5556SXylle        phpCAS::_validateClientExists();
1338*d10b5556SXylle
1339*d10b5556SXylle        return (self::$_PHPCAS_CLIENT->handleLogoutRequests($check_client, $allowed_clients));
1340*d10b5556SXylle    }
1341*d10b5556SXylle
1342*d10b5556SXylle    /**
1343*d10b5556SXylle     * This method returns the URL to be used to login.
1344*d10b5556SXylle     *
1345*d10b5556SXylle     * @return string the login URL
1346*d10b5556SXylle     */
1347*d10b5556SXylle    public static function getServerLoginURL()
1348*d10b5556SXylle    {
1349*d10b5556SXylle        phpCAS::_validateClientExists();
1350*d10b5556SXylle
1351*d10b5556SXylle        return self::$_PHPCAS_CLIENT->getServerLoginURL();
1352*d10b5556SXylle    }
1353*d10b5556SXylle
1354*d10b5556SXylle    /**
1355*d10b5556SXylle     * Set the login URL of the CAS server.
1356*d10b5556SXylle     *
1357*d10b5556SXylle     * @param string $url the login URL
1358*d10b5556SXylle     *
1359*d10b5556SXylle     * @return void
1360*d10b5556SXylle     * @since 0.4.21 by Wyman Chan
1361*d10b5556SXylle     */
1362*d10b5556SXylle    public static function setServerLoginURL($url = '')
1363*d10b5556SXylle    {
1364*d10b5556SXylle        phpCAS :: traceBegin();
1365*d10b5556SXylle        phpCAS::_validateClientExists();
1366*d10b5556SXylle
1367*d10b5556SXylle        try {
1368*d10b5556SXylle            self::$_PHPCAS_CLIENT->setServerLoginURL($url);
1369*d10b5556SXylle        } catch (Exception $e) {
1370*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
1371*d10b5556SXylle        }
1372*d10b5556SXylle
1373*d10b5556SXylle        phpCAS :: traceEnd();
1374*d10b5556SXylle    }
1375*d10b5556SXylle
1376*d10b5556SXylle    /**
1377*d10b5556SXylle     * Set the serviceValidate URL of the CAS server.
1378*d10b5556SXylle     * Used for all CAS versions of URL validations.
1379*d10b5556SXylle     * Examples:
1380*d10b5556SXylle     * CAS 1.0 http://www.exemple.com/validate
1381*d10b5556SXylle     * CAS 2.0 http://www.exemple.com/validateURL
1382*d10b5556SXylle     * CAS 3.0 http://www.exemple.com/p3/serviceValidate
1383*d10b5556SXylle     *
1384*d10b5556SXylle     * @param string $url the serviceValidate URL
1385*d10b5556SXylle     *
1386*d10b5556SXylle     * @return void
1387*d10b5556SXylle     */
1388*d10b5556SXylle    public static function setServerServiceValidateURL($url = '')
1389*d10b5556SXylle    {
1390*d10b5556SXylle        phpCAS :: traceBegin();
1391*d10b5556SXylle        phpCAS::_validateClientExists();
1392*d10b5556SXylle
1393*d10b5556SXylle        try {
1394*d10b5556SXylle            self::$_PHPCAS_CLIENT->setServerServiceValidateURL($url);
1395*d10b5556SXylle        } catch (Exception $e) {
1396*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
1397*d10b5556SXylle        }
1398*d10b5556SXylle
1399*d10b5556SXylle        phpCAS :: traceEnd();
1400*d10b5556SXylle    }
1401*d10b5556SXylle
1402*d10b5556SXylle    /**
1403*d10b5556SXylle     * Set the proxyValidate URL of the CAS server.
1404*d10b5556SXylle     * Used for all CAS versions of proxy URL validations
1405*d10b5556SXylle     * Examples:
1406*d10b5556SXylle     * CAS 1.0 http://www.exemple.com/
1407*d10b5556SXylle     * CAS 2.0 http://www.exemple.com/proxyValidate
1408*d10b5556SXylle     * CAS 3.0 http://www.exemple.com/p3/proxyValidate
1409*d10b5556SXylle     *
1410*d10b5556SXylle     * @param string $url the proxyValidate URL
1411*d10b5556SXylle     *
1412*d10b5556SXylle     * @return void
1413*d10b5556SXylle     */
1414*d10b5556SXylle    public static function setServerProxyValidateURL($url = '')
1415*d10b5556SXylle    {
1416*d10b5556SXylle        phpCAS :: traceBegin();
1417*d10b5556SXylle        phpCAS::_validateClientExists();
1418*d10b5556SXylle
1419*d10b5556SXylle        try {
1420*d10b5556SXylle            self::$_PHPCAS_CLIENT->setServerProxyValidateURL($url);
1421*d10b5556SXylle        } catch (Exception $e) {
1422*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
1423*d10b5556SXylle        }
1424*d10b5556SXylle
1425*d10b5556SXylle        phpCAS :: traceEnd();
1426*d10b5556SXylle    }
1427*d10b5556SXylle
1428*d10b5556SXylle    /**
1429*d10b5556SXylle     * Set the samlValidate URL of the CAS server.
1430*d10b5556SXylle     *
1431*d10b5556SXylle     * @param string $url the samlValidate URL
1432*d10b5556SXylle     *
1433*d10b5556SXylle     * @return void
1434*d10b5556SXylle     */
1435*d10b5556SXylle    public static function setServerSamlValidateURL($url = '')
1436*d10b5556SXylle    {
1437*d10b5556SXylle        phpCAS :: traceBegin();
1438*d10b5556SXylle        phpCAS::_validateClientExists();
1439*d10b5556SXylle
1440*d10b5556SXylle        try {
1441*d10b5556SXylle            self::$_PHPCAS_CLIENT->setServerSamlValidateURL($url);
1442*d10b5556SXylle        } catch (Exception $e) {
1443*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
1444*d10b5556SXylle        }
1445*d10b5556SXylle
1446*d10b5556SXylle        phpCAS :: traceEnd();
1447*d10b5556SXylle    }
1448*d10b5556SXylle
1449*d10b5556SXylle    /**
1450*d10b5556SXylle     * This method returns the URL to be used to logout.
1451*d10b5556SXylle     *
1452*d10b5556SXylle     * @return string the URL to use to log out
1453*d10b5556SXylle     */
1454*d10b5556SXylle    public static function getServerLogoutURL()
1455*d10b5556SXylle    {
1456*d10b5556SXylle        phpCAS::_validateClientExists();
1457*d10b5556SXylle
1458*d10b5556SXylle        return self::$_PHPCAS_CLIENT->getServerLogoutURL();
1459*d10b5556SXylle    }
1460*d10b5556SXylle
1461*d10b5556SXylle    /**
1462*d10b5556SXylle     * Set the logout URL of the CAS server.
1463*d10b5556SXylle     *
1464*d10b5556SXylle     * @param string $url the logout URL
1465*d10b5556SXylle     *
1466*d10b5556SXylle     * @return void
1467*d10b5556SXylle     * @since 0.4.21 by Wyman Chan
1468*d10b5556SXylle     */
1469*d10b5556SXylle    public static function setServerLogoutURL($url = '')
1470*d10b5556SXylle    {
1471*d10b5556SXylle        phpCAS :: traceBegin();
1472*d10b5556SXylle        phpCAS::_validateClientExists();
1473*d10b5556SXylle
1474*d10b5556SXylle        try {
1475*d10b5556SXylle            self::$_PHPCAS_CLIENT->setServerLogoutURL($url);
1476*d10b5556SXylle        } catch (Exception $e) {
1477*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
1478*d10b5556SXylle        }
1479*d10b5556SXylle
1480*d10b5556SXylle        phpCAS :: traceEnd();
1481*d10b5556SXylle    }
1482*d10b5556SXylle
1483*d10b5556SXylle    /**
1484*d10b5556SXylle     * This method is used to logout from CAS.
1485*d10b5556SXylle     *
1486*d10b5556SXylle     * @param string $params an array that contains the optional url and
1487*d10b5556SXylle     * service parameters that will be passed to the CAS server
1488*d10b5556SXylle     *
1489*d10b5556SXylle     * @return void
1490*d10b5556SXylle     */
1491*d10b5556SXylle    public static function logout($params = "")
1492*d10b5556SXylle    {
1493*d10b5556SXylle        phpCAS :: traceBegin();
1494*d10b5556SXylle        phpCAS::_validateClientExists();
1495*d10b5556SXylle
1496*d10b5556SXylle        $parsedParams = array ();
1497*d10b5556SXylle        if ($params != "") {
1498*d10b5556SXylle            if (is_string($params)) {
1499*d10b5556SXylle                phpCAS :: error('method `phpCAS::logout($url)\' is now deprecated, use `phpCAS::logoutWithUrl($url)\' instead');
1500*d10b5556SXylle            }
1501*d10b5556SXylle            if (!is_array($params)) {
1502*d10b5556SXylle                phpCAS :: error('type mismatched for parameter $params (should be `array\')');
1503*d10b5556SXylle            }
1504*d10b5556SXylle            foreach ($params as $key => $value) {
1505*d10b5556SXylle                if ($key != "service" && $key != "url") {
1506*d10b5556SXylle                    phpCAS :: error('only `url\' and `service\' parameters are allowed for method `phpCAS::logout($params)\'');
1507*d10b5556SXylle                }
1508*d10b5556SXylle                $parsedParams[$key] = $value;
1509*d10b5556SXylle            }
1510*d10b5556SXylle        }
1511*d10b5556SXylle        self::$_PHPCAS_CLIENT->logout($parsedParams);
1512*d10b5556SXylle        // never reached
1513*d10b5556SXylle        phpCAS :: traceEnd();
1514*d10b5556SXylle    }
1515*d10b5556SXylle
1516*d10b5556SXylle    /**
1517*d10b5556SXylle     * This method is used to logout from CAS. Halts by redirecting to the CAS
1518*d10b5556SXylle     * server.
1519*d10b5556SXylle     *
1520*d10b5556SXylle     * @param string $service a URL that will be transmitted to the CAS server
1521*d10b5556SXylle     *
1522*d10b5556SXylle     * @return void
1523*d10b5556SXylle     */
1524*d10b5556SXylle    public static function logoutWithRedirectService($service)
1525*d10b5556SXylle    {
1526*d10b5556SXylle        phpCAS :: traceBegin();
1527*d10b5556SXylle        phpCAS::_validateClientExists();
1528*d10b5556SXylle
1529*d10b5556SXylle        if (!is_string($service)) {
1530*d10b5556SXylle            phpCAS :: error('type mismatched for parameter $service (should be `string\')');
1531*d10b5556SXylle        }
1532*d10b5556SXylle        self::$_PHPCAS_CLIENT->logout(array ( "service" => $service ));
1533*d10b5556SXylle        // never reached
1534*d10b5556SXylle        phpCAS :: traceEnd();
1535*d10b5556SXylle    }
1536*d10b5556SXylle
1537*d10b5556SXylle    /**
1538*d10b5556SXylle     * This method is used to logout from CAS. Halts by redirecting to the CAS
1539*d10b5556SXylle     * server.
1540*d10b5556SXylle     *
1541*d10b5556SXylle     * @param string $url a URL that will be transmitted to the CAS server
1542*d10b5556SXylle     *
1543*d10b5556SXylle     * @return void
1544*d10b5556SXylle     * @deprecated The url parameter has been removed from the CAS server as of
1545*d10b5556SXylle     * version 3.3.5.1
1546*d10b5556SXylle     */
1547*d10b5556SXylle    public static function logoutWithUrl($url)
1548*d10b5556SXylle    {
1549*d10b5556SXylle        trigger_error('Function deprecated for cas servers >= 3.3.5.1', E_USER_DEPRECATED);
1550*d10b5556SXylle        phpCAS :: traceBegin();
1551*d10b5556SXylle        if (!is_object(self::$_PHPCAS_CLIENT)) {
1552*d10b5556SXylle            phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
1553*d10b5556SXylle        }
1554*d10b5556SXylle        if (!is_string($url)) {
1555*d10b5556SXylle            phpCAS :: error('type mismatched for parameter $url (should be `string\')');
1556*d10b5556SXylle        }
1557*d10b5556SXylle        self::$_PHPCAS_CLIENT->logout(array ( "url" => $url ));
1558*d10b5556SXylle        // never reached
1559*d10b5556SXylle        phpCAS :: traceEnd();
1560*d10b5556SXylle    }
1561*d10b5556SXylle
1562*d10b5556SXylle    /**
1563*d10b5556SXylle     * This method is used to logout from CAS. Halts by redirecting to the CAS
1564*d10b5556SXylle     * server.
1565*d10b5556SXylle     *
1566*d10b5556SXylle     * @param string $service a URL that will be transmitted to the CAS server
1567*d10b5556SXylle     * @param string $url     a URL that will be transmitted to the CAS server
1568*d10b5556SXylle     *
1569*d10b5556SXylle     * @return void
1570*d10b5556SXylle     *
1571*d10b5556SXylle     * @deprecated The url parameter has been removed from the CAS server as of
1572*d10b5556SXylle     * version 3.3.5.1
1573*d10b5556SXylle     */
1574*d10b5556SXylle    public static function logoutWithRedirectServiceAndUrl($service, $url)
1575*d10b5556SXylle    {
1576*d10b5556SXylle        trigger_error('Function deprecated for cas servers >= 3.3.5.1', E_USER_DEPRECATED);
1577*d10b5556SXylle        phpCAS :: traceBegin();
1578*d10b5556SXylle        phpCAS::_validateClientExists();
1579*d10b5556SXylle
1580*d10b5556SXylle        if (!is_string($service)) {
1581*d10b5556SXylle            phpCAS :: error('type mismatched for parameter $service (should be `string\')');
1582*d10b5556SXylle        }
1583*d10b5556SXylle        if (!is_string($url)) {
1584*d10b5556SXylle            phpCAS :: error('type mismatched for parameter $url (should be `string\')');
1585*d10b5556SXylle        }
1586*d10b5556SXylle        self::$_PHPCAS_CLIENT->logout(
1587*d10b5556SXylle            array (
1588*d10b5556SXylle                "service" => $service,
1589*d10b5556SXylle                "url" => $url
1590*d10b5556SXylle            )
1591*d10b5556SXylle        );
1592*d10b5556SXylle        // never reached
1593*d10b5556SXylle        phpCAS :: traceEnd();
1594*d10b5556SXylle    }
1595*d10b5556SXylle
1596*d10b5556SXylle    /**
1597*d10b5556SXylle     * Set the fixed URL that will be used by the CAS server to transmit the
1598*d10b5556SXylle     * PGT. When this method is not called, a phpCAS script uses its own URL
1599*d10b5556SXylle     * for the callback.
1600*d10b5556SXylle     *
1601*d10b5556SXylle     * @param string $url the URL
1602*d10b5556SXylle     *
1603*d10b5556SXylle     * @return void
1604*d10b5556SXylle     */
1605*d10b5556SXylle    public static function setFixedCallbackURL($url = '')
1606*d10b5556SXylle    {
1607*d10b5556SXylle        phpCAS :: traceBegin();
1608*d10b5556SXylle        phpCAS::_validateProxyExists();
1609*d10b5556SXylle
1610*d10b5556SXylle        try {
1611*d10b5556SXylle            self::$_PHPCAS_CLIENT->setCallbackURL($url);
1612*d10b5556SXylle        } catch (Exception $e) {
1613*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
1614*d10b5556SXylle        }
1615*d10b5556SXylle
1616*d10b5556SXylle        phpCAS :: traceEnd();
1617*d10b5556SXylle    }
1618*d10b5556SXylle
1619*d10b5556SXylle    /**
1620*d10b5556SXylle     * Set the fixed URL that will be set as the CAS service parameter. When this
1621*d10b5556SXylle     * method is not called, a phpCAS script uses its own URL.
1622*d10b5556SXylle     *
1623*d10b5556SXylle     * @param string $url the URL
1624*d10b5556SXylle     *
1625*d10b5556SXylle     * @return void
1626*d10b5556SXylle     */
1627*d10b5556SXylle    public static function setFixedServiceURL($url)
1628*d10b5556SXylle    {
1629*d10b5556SXylle        phpCAS :: traceBegin();
1630*d10b5556SXylle        phpCAS::_validateProxyExists();
1631*d10b5556SXylle
1632*d10b5556SXylle        try {
1633*d10b5556SXylle            self::$_PHPCAS_CLIENT->setURL($url);
1634*d10b5556SXylle        } catch (Exception $e) {
1635*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
1636*d10b5556SXylle        }
1637*d10b5556SXylle
1638*d10b5556SXylle        phpCAS :: traceEnd();
1639*d10b5556SXylle    }
1640*d10b5556SXylle
1641*d10b5556SXylle    /**
1642*d10b5556SXylle     * Get the URL that is set as the CAS service parameter.
1643*d10b5556SXylle     *
1644*d10b5556SXylle     * @return string Service Url
1645*d10b5556SXylle     */
1646*d10b5556SXylle    public static function getServiceURL()
1647*d10b5556SXylle    {
1648*d10b5556SXylle        phpCAS::_validateProxyExists();
1649*d10b5556SXylle        return (self::$_PHPCAS_CLIENT->getURL());
1650*d10b5556SXylle    }
1651*d10b5556SXylle
1652*d10b5556SXylle    /**
1653*d10b5556SXylle     * Retrieve a Proxy Ticket from the CAS server.
1654*d10b5556SXylle     *
1655*d10b5556SXylle     * @param string $target_service Url string of service to proxy
1656*d10b5556SXylle     * @param int &$err_code      error code
1657*d10b5556SXylle     * @param string &$err_msg       error message
1658*d10b5556SXylle     *
1659*d10b5556SXylle     * @return string Proxy Ticket
1660*d10b5556SXylle     */
1661*d10b5556SXylle    public static function retrievePT($target_service, & $err_code, & $err_msg)
1662*d10b5556SXylle    {
1663*d10b5556SXylle        phpCAS::_validateProxyExists();
1664*d10b5556SXylle
1665*d10b5556SXylle        try {
1666*d10b5556SXylle            return (self::$_PHPCAS_CLIENT->retrievePT($target_service, $err_code, $err_msg));
1667*d10b5556SXylle        } catch (Exception $e) {
1668*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
1669*d10b5556SXylle        }
1670*d10b5556SXylle    }
1671*d10b5556SXylle
1672*d10b5556SXylle    /**
1673*d10b5556SXylle     * Set the certificate of the CAS server CA and if the CN should be properly
1674*d10b5556SXylle     * verified.
1675*d10b5556SXylle     *
1676*d10b5556SXylle     * @param string $cert        CA certificate file name
1677*d10b5556SXylle     * @param bool   $validate_cn Validate CN in certificate (default true)
1678*d10b5556SXylle     *
1679*d10b5556SXylle     * @return void
1680*d10b5556SXylle     */
1681*d10b5556SXylle    public static function setCasServerCACert($cert, $validate_cn = true)
1682*d10b5556SXylle    {
1683*d10b5556SXylle        phpCAS :: traceBegin();
1684*d10b5556SXylle        phpCAS::_validateClientExists();
1685*d10b5556SXylle
1686*d10b5556SXylle        try {
1687*d10b5556SXylle            self::$_PHPCAS_CLIENT->setCasServerCACert($cert, $validate_cn);
1688*d10b5556SXylle        } catch (Exception $e) {
1689*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
1690*d10b5556SXylle        }
1691*d10b5556SXylle
1692*d10b5556SXylle        phpCAS :: traceEnd();
1693*d10b5556SXylle    }
1694*d10b5556SXylle
1695*d10b5556SXylle    /**
1696*d10b5556SXylle     * Set no SSL validation for the CAS server.
1697*d10b5556SXylle     *
1698*d10b5556SXylle     * @return void
1699*d10b5556SXylle     */
1700*d10b5556SXylle    public static function setNoCasServerValidation()
1701*d10b5556SXylle    {
1702*d10b5556SXylle        phpCAS :: traceBegin();
1703*d10b5556SXylle        phpCAS::_validateClientExists();
1704*d10b5556SXylle
1705*d10b5556SXylle        phpCAS :: trace('You have configured no validation of the legitimacy of the cas server. This is not recommended for production use.');
1706*d10b5556SXylle        self::$_PHPCAS_CLIENT->setNoCasServerValidation();
1707*d10b5556SXylle        phpCAS :: traceEnd();
1708*d10b5556SXylle    }
1709*d10b5556SXylle
1710*d10b5556SXylle
1711*d10b5556SXylle    /**
1712*d10b5556SXylle     * Disable the removal of a CAS-Ticket from the URL when authenticating
1713*d10b5556SXylle     * DISABLING POSES A SECURITY RISK:
1714*d10b5556SXylle     * We normally remove the ticket by an additional redirect as a security
1715*d10b5556SXylle     * precaution to prevent a ticket in the HTTP_REFERRER or be carried over in
1716*d10b5556SXylle     * the URL parameter
1717*d10b5556SXylle     *
1718*d10b5556SXylle     * @return void
1719*d10b5556SXylle     */
1720*d10b5556SXylle    public static function setNoClearTicketsFromUrl()
1721*d10b5556SXylle    {
1722*d10b5556SXylle        phpCAS :: traceBegin();
1723*d10b5556SXylle        phpCAS::_validateClientExists();
1724*d10b5556SXylle
1725*d10b5556SXylle        self::$_PHPCAS_CLIENT->setNoClearTicketsFromUrl();
1726*d10b5556SXylle        phpCAS :: traceEnd();
1727*d10b5556SXylle    }
1728*d10b5556SXylle
1729*d10b5556SXylle    /** @} */
1730*d10b5556SXylle
1731*d10b5556SXylle    /**
1732*d10b5556SXylle     * Change CURL options.
1733*d10b5556SXylle     * CURL is used to connect through HTTPS to CAS server
1734*d10b5556SXylle     *
1735*d10b5556SXylle     * @param string $key   the option key
1736*d10b5556SXylle     * @param string $value the value to set
1737*d10b5556SXylle     *
1738*d10b5556SXylle     * @return void
1739*d10b5556SXylle     */
1740*d10b5556SXylle    public static function setExtraCurlOption($key, $value)
1741*d10b5556SXylle    {
1742*d10b5556SXylle        phpCAS :: traceBegin();
1743*d10b5556SXylle        phpCAS::_validateClientExists();
1744*d10b5556SXylle
1745*d10b5556SXylle        self::$_PHPCAS_CLIENT->setExtraCurlOption($key, $value);
1746*d10b5556SXylle        phpCAS :: traceEnd();
1747*d10b5556SXylle    }
1748*d10b5556SXylle
1749*d10b5556SXylle    /**
1750*d10b5556SXylle     * Set a salt/seed for the session-id hash to make it harder to guess.
1751*d10b5556SXylle     *
1752*d10b5556SXylle     * When $changeSessionID = true phpCAS will create a session-id that is derived
1753*d10b5556SXylle     * from the service ticket. Doing so allows phpCAS to look-up and destroy the
1754*d10b5556SXylle     * proper session on single-log-out requests. While the service tickets
1755*d10b5556SXylle     * provided by the CAS server may include enough data to generate a strong
1756*d10b5556SXylle     * hash, clients may provide an additional salt to ensure that session ids
1757*d10b5556SXylle     * are not guessable if the session tickets do not have enough entropy.
1758*d10b5556SXylle     *
1759*d10b5556SXylle     * @param string $salt The salt to combine with the session ticket.
1760*d10b5556SXylle     *
1761*d10b5556SXylle     * @return void
1762*d10b5556SXylle     */
1763*d10b5556SXylle     public static function setSessionIdSalt($salt) {
1764*d10b5556SXylle       phpCAS :: traceBegin();
1765*d10b5556SXylle       phpCAS::_validateClientExists();
1766*d10b5556SXylle       self::$_PHPCAS_CLIENT->setSessionIdSalt($salt);
1767*d10b5556SXylle       phpCAS :: traceEnd();
1768*d10b5556SXylle     }
1769*d10b5556SXylle
1770*d10b5556SXylle    /**
1771*d10b5556SXylle     * If you want your service to be proxied you have to enable it (default
1772*d10b5556SXylle     * disabled) and define an accepable list of proxies that are allowed to
1773*d10b5556SXylle     * proxy your service.
1774*d10b5556SXylle     *
1775*d10b5556SXylle     * Add each allowed proxy definition object. For the normal CAS_ProxyChain
1776*d10b5556SXylle     * class, the constructor takes an array of proxies to match. The list is in
1777*d10b5556SXylle     * reverse just as seen from the service. Proxies have to be defined in reverse
1778*d10b5556SXylle     * from the service to the user. If a user hits service A and gets proxied via
1779*d10b5556SXylle     * B to service C the list of acceptable on C would be array(B,A). The definition
1780*d10b5556SXylle     * of an individual proxy can be either a string or a regexp (preg_match is used)
1781*d10b5556SXylle     * that will be matched against the proxy list supplied by the cas server
1782*d10b5556SXylle     * when validating the proxy tickets. The strings are compared starting from
1783*d10b5556SXylle     * the beginning and must fully match with the proxies in the list.
1784*d10b5556SXylle     * Example:
1785*d10b5556SXylle     * 		phpCAS::allowProxyChain(new CAS_ProxyChain(array(
1786*d10b5556SXylle     *				'https://app.example.com/'
1787*d10b5556SXylle     *			)));
1788*d10b5556SXylle     * 		phpCAS::allowProxyChain(new CAS_ProxyChain(array(
1789*d10b5556SXylle     *				'/^https:\/\/app[0-9]\.example\.com\/rest\//',
1790*d10b5556SXylle     *				'http://client.example.com/'
1791*d10b5556SXylle     *			)));
1792*d10b5556SXylle     *
1793*d10b5556SXylle     * For quick testing or in certain production screnarios you might want to
1794*d10b5556SXylle     * allow allow any other valid service to proxy your service. To do so, add
1795*d10b5556SXylle     * the "Any" chain:
1796*d10b5556SXylle     *		phpCAS::allowProxyChain(new CAS_ProxyChain_Any);
1797*d10b5556SXylle     * THIS SETTING IS HOWEVER NOT RECOMMENDED FOR PRODUCTION AND HAS SECURITY
1798*d10b5556SXylle     * IMPLICATIONS: YOU ARE ALLOWING ANY SERVICE TO ACT ON BEHALF OF A USER
1799*d10b5556SXylle     * ON THIS SERVICE.
1800*d10b5556SXylle     *
1801*d10b5556SXylle     * @param CAS_ProxyChain_Interface $proxy_chain A proxy-chain that will be
1802*d10b5556SXylle     * matched against the proxies requesting access
1803*d10b5556SXylle     *
1804*d10b5556SXylle     * @return void
1805*d10b5556SXylle     */
1806*d10b5556SXylle    public static function allowProxyChain(CAS_ProxyChain_Interface $proxy_chain)
1807*d10b5556SXylle    {
1808*d10b5556SXylle        phpCAS :: traceBegin();
1809*d10b5556SXylle        phpCAS::_validateClientExists();
1810*d10b5556SXylle
1811*d10b5556SXylle        if (self::$_PHPCAS_CLIENT->getServerVersion() !== CAS_VERSION_2_0
1812*d10b5556SXylle            && self::$_PHPCAS_CLIENT->getServerVersion() !== CAS_VERSION_3_0
1813*d10b5556SXylle        ) {
1814*d10b5556SXylle            phpCAS :: error('this method can only be used with the cas 2.0/3.0 protocols');
1815*d10b5556SXylle        }
1816*d10b5556SXylle        self::$_PHPCAS_CLIENT->getAllowedProxyChains()->allowProxyChain($proxy_chain);
1817*d10b5556SXylle        phpCAS :: traceEnd();
1818*d10b5556SXylle    }
1819*d10b5556SXylle
1820*d10b5556SXylle    /**
1821*d10b5556SXylle     * Answer an array of proxies that are sitting in front of this application.
1822*d10b5556SXylle     * This method will only return a non-empty array if we have received and
1823*d10b5556SXylle     * validated a Proxy Ticket.
1824*d10b5556SXylle     *
1825*d10b5556SXylle     * @return array
1826*d10b5556SXylle     * @access public
1827*d10b5556SXylle     * @since 6/25/09
1828*d10b5556SXylle     */
1829*d10b5556SXylle    public static function getProxies ()
1830*d10b5556SXylle    {
1831*d10b5556SXylle        phpCAS::_validateProxyExists();
1832*d10b5556SXylle
1833*d10b5556SXylle        return(self::$_PHPCAS_CLIENT->getProxies());
1834*d10b5556SXylle    }
1835*d10b5556SXylle
1836*d10b5556SXylle    // ########################################################################
1837*d10b5556SXylle    // PGTIOU/PGTID and logoutRequest rebroadcasting
1838*d10b5556SXylle    // ########################################################################
1839*d10b5556SXylle
1840*d10b5556SXylle    /**
1841*d10b5556SXylle     * Add a pgtIou/pgtId and logoutRequest rebroadcast node.
1842*d10b5556SXylle     *
1843*d10b5556SXylle     * @param string $rebroadcastNodeUrl The rebroadcast node URL. Can be
1844*d10b5556SXylle     * hostname or IP.
1845*d10b5556SXylle     *
1846*d10b5556SXylle     * @return void
1847*d10b5556SXylle     */
1848*d10b5556SXylle    public static function addRebroadcastNode($rebroadcastNodeUrl)
1849*d10b5556SXylle    {
1850*d10b5556SXylle        phpCAS::traceBegin();
1851*d10b5556SXylle        phpCAS::log('rebroadcastNodeUrl:'.$rebroadcastNodeUrl);
1852*d10b5556SXylle        phpCAS::_validateClientExists();
1853*d10b5556SXylle
1854*d10b5556SXylle        try {
1855*d10b5556SXylle            self::$_PHPCAS_CLIENT->addRebroadcastNode($rebroadcastNodeUrl);
1856*d10b5556SXylle        } catch (Exception $e) {
1857*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
1858*d10b5556SXylle        }
1859*d10b5556SXylle
1860*d10b5556SXylle        phpCAS::traceEnd();
1861*d10b5556SXylle    }
1862*d10b5556SXylle
1863*d10b5556SXylle    /**
1864*d10b5556SXylle     * This method is used to add header parameters when rebroadcasting
1865*d10b5556SXylle     * pgtIou/pgtId or logoutRequest.
1866*d10b5556SXylle     *
1867*d10b5556SXylle     * @param String $header Header to send when rebroadcasting.
1868*d10b5556SXylle     *
1869*d10b5556SXylle     * @return void
1870*d10b5556SXylle     */
1871*d10b5556SXylle    public static function addRebroadcastHeader($header)
1872*d10b5556SXylle    {
1873*d10b5556SXylle        phpCAS :: traceBegin();
1874*d10b5556SXylle        phpCAS::_validateClientExists();
1875*d10b5556SXylle
1876*d10b5556SXylle        try {
1877*d10b5556SXylle            self::$_PHPCAS_CLIENT->addRebroadcastHeader($header);
1878*d10b5556SXylle        } catch (Exception $e) {
1879*d10b5556SXylle            phpCAS :: error(get_class($e) . ': ' . $e->getMessage());
1880*d10b5556SXylle        }
1881*d10b5556SXylle
1882*d10b5556SXylle        phpCAS :: traceEnd();
1883*d10b5556SXylle    }
1884*d10b5556SXylle
1885*d10b5556SXylle    /**
1886*d10b5556SXylle     * Checks if a client already exists
1887*d10b5556SXylle     *
1888*d10b5556SXylle     * @throws CAS_OutOfSequenceBeforeClientException
1889*d10b5556SXylle     *
1890*d10b5556SXylle     * @return void
1891*d10b5556SXylle     */
1892*d10b5556SXylle    private static function _validateClientExists()
1893*d10b5556SXylle    {
1894*d10b5556SXylle        if (!is_object(self::$_PHPCAS_CLIENT)) {
1895*d10b5556SXylle            throw new CAS_OutOfSequenceBeforeClientException();
1896*d10b5556SXylle        }
1897*d10b5556SXylle    }
1898*d10b5556SXylle
1899*d10b5556SXylle    /**
1900*d10b5556SXylle     * Checks of a proxy client aready exists
1901*d10b5556SXylle     *
1902*d10b5556SXylle     * @throws CAS_OutOfSequenceBeforeProxyException
1903*d10b5556SXylle     *
1904*d10b5556SXylle     * @return void
1905*d10b5556SXylle     */
1906*d10b5556SXylle    private static function _validateProxyExists()
1907*d10b5556SXylle    {
1908*d10b5556SXylle        if (!is_object(self::$_PHPCAS_CLIENT)) {
1909*d10b5556SXylle            throw new CAS_OutOfSequenceBeforeProxyException();
1910*d10b5556SXylle        }
1911*d10b5556SXylle    }
1912*d10b5556SXylle
1913*d10b5556SXylle    /**
1914*d10b5556SXylle     * @return CAS_Client
1915*d10b5556SXylle     */
1916*d10b5556SXylle    public static function getCasClient()
1917*d10b5556SXylle    {
1918*d10b5556SXylle        return self::$_PHPCAS_CLIENT;
1919*d10b5556SXylle    }
1920*d10b5556SXylle
1921*d10b5556SXylle    /**
1922*d10b5556SXylle     * For testing purposes, use this method to set the client to a test double
1923*d10b5556SXylle     *
1924*d10b5556SXylle     * @return void
1925*d10b5556SXylle     */
1926*d10b5556SXylle    public static function setCasClient(\CAS_Client $client)
1927*d10b5556SXylle    {
1928*d10b5556SXylle        self::$_PHPCAS_CLIENT = $client;
1929*d10b5556SXylle    }
1930*d10b5556SXylle}
1931*d10b5556SXylle// ########################################################################
1932*d10b5556SXylle// DOCUMENTATION
1933*d10b5556SXylle// ########################################################################
1934*d10b5556SXylle
1935*d10b5556SXylle// ########################################################################
1936*d10b5556SXylle//  MAIN PAGE
1937*d10b5556SXylle
1938*d10b5556SXylle/**
1939*d10b5556SXylle * @mainpage
1940*d10b5556SXylle *
1941*d10b5556SXylle * The following pages only show the source documentation.
1942*d10b5556SXylle *
1943*d10b5556SXylle */
1944*d10b5556SXylle
1945*d10b5556SXylle// ########################################################################
1946*d10b5556SXylle//  MODULES DEFINITION
1947*d10b5556SXylle
1948*d10b5556SXylle/** @defgroup public User interface */
1949*d10b5556SXylle
1950*d10b5556SXylle/** @defgroup publicInit Initialization
1951*d10b5556SXylle *  @ingroup public */
1952*d10b5556SXylle
1953*d10b5556SXylle/** @defgroup publicAuth Authentication
1954*d10b5556SXylle *  @ingroup public */
1955*d10b5556SXylle
1956*d10b5556SXylle/** @defgroup publicServices Access to external services
1957*d10b5556SXylle *  @ingroup public */
1958*d10b5556SXylle
1959*d10b5556SXylle/** @defgroup publicConfig Configuration
1960*d10b5556SXylle *  @ingroup public */
1961*d10b5556SXylle
1962*d10b5556SXylle/** @defgroup publicLang Internationalization
1963*d10b5556SXylle *  @ingroup publicConfig */
1964*d10b5556SXylle
1965*d10b5556SXylle/** @defgroup publicOutput HTML output
1966*d10b5556SXylle *  @ingroup publicConfig */
1967*d10b5556SXylle
1968*d10b5556SXylle/** @defgroup publicPGTStorage PGT storage
1969*d10b5556SXylle *  @ingroup publicConfig */
1970*d10b5556SXylle
1971*d10b5556SXylle/** @defgroup publicDebug Debugging
1972*d10b5556SXylle *  @ingroup public */
1973*d10b5556SXylle
1974*d10b5556SXylle/** @defgroup internal Implementation */
1975*d10b5556SXylle
1976*d10b5556SXylle/** @defgroup internalAuthentication Authentication
1977*d10b5556SXylle *  @ingroup internal */
1978*d10b5556SXylle
1979*d10b5556SXylle/** @defgroup internalBasic CAS Basic client features (CAS 1.0, Service Tickets)
1980*d10b5556SXylle *  @ingroup internal */
1981*d10b5556SXylle
1982*d10b5556SXylle/** @defgroup internalProxy CAS Proxy features (CAS 2.0, Proxy Granting Tickets)
1983*d10b5556SXylle *  @ingroup internal */
1984*d10b5556SXylle
1985*d10b5556SXylle/** @defgroup internalSAML CAS SAML features (SAML 1.1)
1986*d10b5556SXylle *  @ingroup internal */
1987*d10b5556SXylle
1988*d10b5556SXylle/** @defgroup internalPGTStorage PGT storage
1989*d10b5556SXylle *  @ingroup internalProxy */
1990*d10b5556SXylle
1991*d10b5556SXylle/** @defgroup internalPGTStorageDb PGT storage in a database
1992*d10b5556SXylle *  @ingroup internalPGTStorage */
1993*d10b5556SXylle
1994*d10b5556SXylle/** @defgroup internalPGTStorageFile PGT storage on the filesystem
1995*d10b5556SXylle *  @ingroup internalPGTStorage */
1996*d10b5556SXylle
1997*d10b5556SXylle/** @defgroup internalCallback Callback from the CAS server
1998*d10b5556SXylle *  @ingroup internalProxy */
1999*d10b5556SXylle
2000*d10b5556SXylle/** @defgroup internalProxyServices Proxy other services
2001*d10b5556SXylle *  @ingroup internalProxy */
2002*d10b5556SXylle
2003*d10b5556SXylle/** @defgroup internalService CAS client features (CAS 2.0, Proxied service)
2004*d10b5556SXylle *  @ingroup internal */
2005*d10b5556SXylle
2006*d10b5556SXylle/** @defgroup internalConfig Configuration
2007*d10b5556SXylle *  @ingroup internal */
2008*d10b5556SXylle
2009*d10b5556SXylle/** @defgroup internalBehave Internal behaviour of phpCAS
2010*d10b5556SXylle *  @ingroup internalConfig */
2011*d10b5556SXylle
2012*d10b5556SXylle/** @defgroup internalOutput HTML output
2013*d10b5556SXylle *  @ingroup internalConfig */
2014*d10b5556SXylle
2015*d10b5556SXylle/** @defgroup internalLang Internationalization
2016*d10b5556SXylle *  @ingroup internalConfig
2017*d10b5556SXylle *
2018*d10b5556SXylle * To add a new language:
2019*d10b5556SXylle * - 1. define a new constant PHPCAS_LANG_XXXXXX in CAS/CAS.php
2020*d10b5556SXylle * - 2. copy any file from CAS/languages to CAS/languages/XXXXXX.php
2021*d10b5556SXylle * - 3. Make the translations
2022*d10b5556SXylle */
2023*d10b5556SXylle
2024*d10b5556SXylle/** @defgroup internalDebug Debugging
2025*d10b5556SXylle *  @ingroup internal */
2026*d10b5556SXylle
2027*d10b5556SXylle/** @defgroup internalMisc Miscellaneous
2028*d10b5556SXylle *  @ingroup internal */
2029*d10b5556SXylle
2030*d10b5556SXylle// ########################################################################
2031*d10b5556SXylle//  EXAMPLES
2032*d10b5556SXylle
2033*d10b5556SXylle/**
2034*d10b5556SXylle * @example example_simple.php
2035*d10b5556SXylle */
2036*d10b5556SXylle/**
2037*d10b5556SXylle * @example example_service.php
2038*d10b5556SXylle */
2039*d10b5556SXylle/**
2040*d10b5556SXylle * @example example_service_that_proxies.php
2041*d10b5556SXylle */
2042*d10b5556SXylle/**
2043*d10b5556SXylle * @example example_service_POST.php
2044*d10b5556SXylle */
2045*d10b5556SXylle/**
2046*d10b5556SXylle * @example example_proxy_serviceWeb.php
2047*d10b5556SXylle */
2048*d10b5556SXylle/**
2049*d10b5556SXylle * @example example_proxy_serviceWeb_chaining.php
2050*d10b5556SXylle */
2051*d10b5556SXylle/**
2052*d10b5556SXylle * @example example_proxy_POST.php
2053*d10b5556SXylle */
2054*d10b5556SXylle/**
2055*d10b5556SXylle * @example example_proxy_GET.php
2056*d10b5556SXylle */
2057*d10b5556SXylle/**
2058*d10b5556SXylle * @example example_lang.php
2059*d10b5556SXylle */
2060*d10b5556SXylle/**
2061*d10b5556SXylle * @example example_html.php
2062*d10b5556SXylle */
2063*d10b5556SXylle/**
2064*d10b5556SXylle * @example example_pgt_storage_file.php
2065*d10b5556SXylle */
2066*d10b5556SXylle/**
2067*d10b5556SXylle * @example example_pgt_storage_db.php
2068*d10b5556SXylle */
2069*d10b5556SXylle/**
2070*d10b5556SXylle * @example example_gateway.php
2071*d10b5556SXylle */
2072*d10b5556SXylle/**
2073*d10b5556SXylle * @example example_logout.php
2074*d10b5556SXylle */
2075*d10b5556SXylle/**
2076*d10b5556SXylle * @example example_rebroadcast.php
2077*d10b5556SXylle */
2078*d10b5556SXylle/**
2079*d10b5556SXylle * @example example_custom_urls.php
2080*d10b5556SXylle */
2081*d10b5556SXylle/**
2082*d10b5556SXylle * @example example_advanced_saml11.php
2083*d10b5556SXylle */
2084