Passed
Push — master ( 38fbdf...ca585a )
by Tim
02:00
created

www/login.php (1 issue)

Labels
Severity
1
<?php
2
3
/*
4
 *    simpleSAMLphp-casserver is a CAS 1.0 and 2.0 compliant CAS server in the form of a simpleSAMLphp module
5
 *
6
 *    Copyright (C) 2013  Bjorn R. Jensen
7
 *
8
 *    This library is free software; you can redistribute it and/or
9
 *    modify it under the terms of the GNU Lesser General Public
10
 *    License as published by the Free Software Foundation; either
11
 *    version 2.1 of the License, or (at your option) any later version.
12
 *
13
 *    This library is distributed in the hope that it will be useful,
14
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 *    Lesser General Public License for more details.
17
 *
18
 *    You should have received a copy of the GNU Lesser General Public
19
 *    License along with this library; if not, write to the Free Software
20
 *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21
 *
22
 * Incoming parameters:
23
 *  service
24
 *  renew
25
 *  gateway
26
 *  entityId
27
 *  scope
28
 *  language
29
 */
30
31
use SimpleSAML\Module\casserver\Cas\AttributeExtractor;
32
use SimpleSAML\Module\casserver\Cas\Protocol\SamlValidateResponder;
33
use SimpleSAML\Module\casserver\Cas\ServiceValidator;
34
use SimpleSAML\Module\casserver\Cas\Ticket\TicketFactory;
35
use SimpleSAML\Module\casserver\Cas\Ticket\TicketStore;
36
use SimpleSAML\Configuration;
37
use SimpleSAML\Locale\Language;
38
use SimpleSAML\Logger;
39
use SimpleSAML\Module;
40
use SimpleSAML\Session;
41
use SimpleSAML\Utils\HTTP;
42
43
require_once('utility/urlUtils.php');
44
45
$forceAuthn = isset($_GET['renew']) && $_GET['renew'];
46
$isPassive = isset($_GET['gateway']) && $_GET['gateway'];
47
// Determine if client wants us to post or redirect the response. Default is redirect.
48
$redirect = !(isset($_GET['method']) && 'POST' === $_GET['method']);
49
50
$casconfig = Configuration::getConfig('module_casserver.php');
51
$serviceValidator = new ServiceValidator($casconfig);
52
53
$serviceUrl = $_GET['service'] ?? $_GET['TARGET'] ?? null;
54
55
if (isset($serviceUrl)) {
56
    $serviceCasConfig = $serviceValidator->checkServiceURL(sanitize($serviceUrl));
57
    if (isset($serviceCasConfig)) {
58
        // Override the cas configuration to use for this service
59
        $casconfig = $serviceCasConfig;
60
    } else {
61
        $message = 'Service parameter provided to CAS server is not listed as a legal service: [service] = ' .
62
            var_export($serviceUrl, true);
63
        Logger::debug('casserver:' . $message);
64
65
        throw new \Exception($message);
66
    }
67
}
68
69
70
$as = new \SimpleSAML\Auth\Simple($casconfig->getValue('authsource'));
0 ignored issues
show
It seems like $casconfig->getValue('authsource') can also be of type null; however, parameter $authSource of SimpleSAML\Auth\Simple::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

70
$as = new \SimpleSAML\Auth\Simple(/** @scrutinizer ignore-type */ $casconfig->getValue('authsource'));
Loading history...
71
72
if (array_key_exists('scope', $_GET) && is_string($_GET['scope'])) {
73
    $scopes = $casconfig->getValue('scopes', []);
74
75
    if (array_key_exists($_GET['scope'], $scopes)) {
76
        $idpList = $scopes[$_GET['scope']];
77
    } else {
78
        $message = 'Scope parameter provided to CAS server is not listed as legal scope: [scope] = ' .
79
            var_export($_GET['scope'], true);
80
        Logger::debug('casserver:' . $message);
81
82
        throw new \Exception($message);
83
    }
84
}
85
86
if (array_key_exists('language', $_GET) && is_string($_GET['language'])) {
87
    Language::setLanguageCookie($_GET['language']);
88
}
89
90
$ticketStoreConfig = $casconfig->getValue('ticketstore', ['class' => 'casserver:FileSystemTicketStore']);
91
$ticketStoreClass = Module::resolveClass($ticketStoreConfig['class'], 'Cas_Ticket');
92
/** @var $ticketStore TicketStore */
93
/** @psalm-suppress InvalidStringClass */
94
$ticketStore = new $ticketStoreClass($casconfig);
95
96
$ticketFactoryClass = Module::resolveClass('casserver:TicketFactory', 'Cas_Ticket');
97
/** @var $ticketFactory TicketFactory */
98
/** @psalm-suppress InvalidStringClass */
99
$ticketFactory = new $ticketFactoryClass($casconfig);
100
101
$session = Session::getSessionFromRequest();
102
103
$sessionTicket = $ticketStore->getTicket($session->getSessionId());
104
$sessionRenewId = $sessionTicket ? $sessionTicket['renewId'] : null;
105
$requestRenewId = isset($_REQUEST['renewId']) ? $_REQUEST['renewId'] : null;
106
107
if (!$as->isAuthenticated() || ($forceAuthn && $sessionRenewId != $requestRenewId)) {
108
    $query = [];
109
110
    if ($sessionRenewId && $forceAuthn) {
111
        $query['renewId'] = $sessionRenewId;
112
    }
113
114
    if (isset($_REQUEST['service'])) {
115
        $query['service'] = $_REQUEST['service'];
116
    }
117
118
    if (isset($_REQUEST['TARGET'])) {
119
        $query['TARGET'] = $_REQUEST['TARGET'];
120
    }
121
122
    if (isset($_REQUEST['method'])) {
123
        $query['method'] = $_REQUEST['method'];
124
    }
125
126
    if (isset($_REQUEST['renew'])) {
127
        $query['renew'] = $_REQUEST['renew'];
128
    }
129
130
    if (isset($_REQUEST['gateway'])) {
131
        $query['gateway'] = $_REQUEST['gateway'];
132
    }
133
134
    if (array_key_exists('language', $_GET)) {
135
        $query['language'] = is_string($_GET['language']) ? $_GET['language'] : null;
136
    }
137
138
    if (isset($_REQUEST['debugMode'])) {
139
        $query['debugMode'] = $_REQUEST['debugMode'];
140
    }
141
142
    $returnUrl = HTTP::getSelfURLNoQuery() . '?' . http_build_query($query);
143
144
    $params = [
145
        'ForceAuthn' => $forceAuthn,
146
        'isPassive' => $isPassive,
147
        'ReturnTo' => $returnUrl,
148
    ];
149
150
    if (isset($_GET['entityId'])) {
151
        $params['saml:idp'] = $_GET['entityId'];
152
    }
153
154
    if (isset($idpList)) {
155
        if (sizeof($idpList) > 1) {
156
            $params['saml:IDPList'] = $idpList;
157
        } else {
158
            $params['saml:idp'] = $idpList[0];
159
        }
160
    }
161
162
    $as->login($params);
163
}
164
165
$sessionExpiry = $as->getAuthData('Expire');
166
167
if (!is_array($sessionTicket) || $forceAuthn) {
168
    $sessionTicket = $ticketFactory->createSessionTicket($session->getSessionId(), $sessionExpiry);
169
170
    $ticketStore->addTicket($sessionTicket);
171
}
172
173
$parameters = [];
174
175
if (array_key_exists('language', $_GET)) {
176
    $oldLanguagePreferred = Language::getLanguageCookie();
177
178
    if (isset($oldLanguagePreferred)) {
179
        $parameters['language'] = $oldLanguagePreferred;
180
    } else {
181
        if (is_string($_GET['language'])) {
182
            $parameters['language'] = $_GET['language'];
183
        }
184
    }
185
}
186
187
if (isset($serviceUrl)) {
188
    $defaultTicketName = isset($_GET['service']) ? 'ticket' : 'SAMLart';
189
    $ticketName = $casconfig->getValue('ticketName', $defaultTicketName);
190
191
    $attributeExtractor = new AttributeExtractor();
192
    $mappedAttributes = $attributeExtractor->extractUserAndAttributes($as->getAttributes(), $casconfig);
193
194
    $serviceTicket = $ticketFactory->createServiceTicket([
195
        'service' => $serviceUrl,
196
        'forceAuthn' => $forceAuthn,
197
        'userName' => $mappedAttributes['user'],
198
        'attributes' => $mappedAttributes['attributes'],
199
        'proxies' => [],
200
        'sessionId' => $sessionTicket['id']
201
    ]);
202
203
    $ticketStore->addTicket($serviceTicket);
204
205
    $parameters[$ticketName] = $serviceTicket['id'];
206
207
    $validDebugModes = ['true', 'samlValidate'];
208
    if (
209
        array_key_exists('debugMode', $_GET) &&
210
        in_array($_GET['debugMode'], $validDebugModes) &&
211
        $casconfig->getBoolean('debugMode', false)
212
    ) {
213
        if ($_GET['debugMode'] === 'samlValidate') {
214
            $samlValidate = new SamlValidateResponder();
215
            $samlResponse = $samlValidate->convertToSaml($serviceTicket);
216
            $soap = $samlValidate->wrapInSoap($samlResponse);
217
            echo '<pre>' . htmlspecialchars($soap) . '</pre>';
218
        } else {
219
            $method = 'serviceValidate';
220
            // Fake some options for validateTicket
221
            $_GET[$ticketName] = $serviceTicket['id'];
222
            // We want to capture the output from echo used in validateTicket
223
            ob_start();
224
            require_once 'utility/validateTicket.php';
225
            $casResponse = ob_get_contents();
226
            ob_end_clean();
227
            echo '<pre>' . htmlspecialchars($casResponse) . '</pre>';
228
        }
229
    } elseif ($redirect) {
230
        HTTP::redirectTrustedURL(HTTP::addURLParameters($serviceUrl, $parameters));
231
    } else {
232
        HTTP::submitPOSTData($serviceUrl, $parameters);
233
    }
234
} else {
235
    HTTP::redirectTrustedURL(
236
        HTTP::addURLParameters(Module::getModuleURL('casserver/loggedIn.php'), $parameters)
237
    );
238
}
239