Issues (173)

Security Analysis    13 potential vulnerabilities

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  Response Splitting (3)
Response Splitting can be used to send arbitrary responses.
  File Manipulation (6)
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Cross-Site Scripting (1)
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

devices/eap_config/DeviceXML.php (2 issues)

1
<?php
2
3
/*
4
 * *****************************************************************************
5
 * Contributions to this work were made on behalf of the GÉANT project, a 
6
 * project that has received funding from the European Union’s Framework 
7
 * Programme 7 under Grant Agreements No. 238875 (GN3) and No. 605243 (GN3plus),
8
 * Horizon 2020 research and innovation programme under Grant Agreements No. 
9
 * 691567 (GN4-1) and No. 731122 (GN4-2).
10
 * On behalf of the aforementioned projects, GEANT Association is the sole owner
11
 * of the copyright in all material which was developed by a member of the GÉANT
12
 * project. GÉANT Vereniging (Association) is registered with the Chamber of 
13
 * Commerce in Amsterdam with registration number 40535155 and operates in the 
14
 * UK as a branch of GÉANT Vereniging.
15
 * 
16
 * Registered office: Hoekenrode 3, 1102BR Amsterdam, The Netherlands. 
17
 * UK branch address: City House, 126-130 Hills Road, Cambridge CB2 1PQ, UK
18
 *
19
 * License: see the web/copyright.inc.php file in the file structure or
20
 *          <base_url>/copyright.php after deploying the software
21
 */
22
23
/**
24
 * This file defines an abstract class used for generic XML
25
 * devices
26
 * actual modules only define available EAP types.
27
 *
28
 * @author Maja Gorecka-Wolniewicz <[email protected]>
29
 * @author Tomasz Wolniewicz <[email protected]>
30
 *
31
 * @package ModuleWriting
32
 */
33
34
namespace devices\eap_config;
35
36
use Exception;
37
38
/**
39
 * This class implements full functionality of the generic XML device
40
 * the only function of the extensions of this class is to specify
41
 * supported EAP methods.
42
 * Instead of specifying supported EAPS an extension can set $all_eaps to true
43
 * this will cause the installer to configure all EAP methods supported by 
44
 * the current profile and declared by the given device.
45
 */
46
abstract class DeviceXML extends \core\DeviceConfig
47
{
48
    
49
    /**
50
     *  @var array $AuthMethodElements is used to limit
51
     *  XML elements present within ServerSideCredentials and
52
     *  ClientSideCredentials to ones which are relevant
53
     *  for a given EAP method.
54
     *  @var array of XLM element names which are allowed
55
     *  EAP method names are defined in core/EAP.php
56
     */
57
    private $authMethodElements = [
58
        'server' => [
59
            \core\common\EAP::TLS => ['CA', 'ServerID'],
60
            \core\common\EAP::FAST => ['CA', 'ServerID'],
61
            \core\common\EAP::PEAP => ['CA', 'ServerID'],
62
            \core\common\EAP::TTLS => ['CA', 'ServerID'],
63
            \core\common\EAP::PWD => ['ServerID'],
64
        ],
65
        'client' => [
66
            \core\common\EAP::TLS => ['UserName', 'Password', 'ClientCertificate'],
67
            \core\common\EAP::NE_MSCHAP2 => ['UserName', 'Password', 'OuterIdentity', 'InnerIdentitySuffix', 'InnerIdentityHint'],
68
            \core\common\EAP::MSCHAP2 => ['UserName', 'Password', 'OuterIdentity', 'InnerIdentitySuffix', 'InnerIdentityHint'],
69
            \core\common\EAP::GTC => ['UserName', 'OneTimeToken'],
70
            \core\common\EAP::NE_PAP => ['UserName', 'Password', 'OuterIdentity', 'InnerIdentitySuffix', 'InnerIdentityHint'],
71
            \core\common\EAP::NE_SILVERBULLET => ['UserName', 'ClientCertificate', 'OuterIdentity'],
72
            \core\common\EAP::NONE => [],
73
        ]
74
    ];
75
76
    /**
77
     * construct the device
78
     */
79
    public function __construct()
80
    {
81
        parent::__construct();
82
    }
83
84
    /**
85
     * $langScope can be 'global' when all lang and all lang-specific information
86
     * is dumped or 'single' when only the selected lang (and defaults) are passed
87
     * NOTICE: 'global' is not yet supported
88
     * 
89
     * @var string
90
     */
91
    public $langScope;
92
93
    /**
94
     * whether all EAP types should be included in the file or only the 
95
     * preferred one
96
     * 
97
     * @var boolean
98
     */
99
    public $allEaps = false;
100
101
    /**
102
     * vendor-specific additional information, this is nit yest fully
103
     * implemented due to lack of use cases.
104
     * 
105
     * @var array
106
     */
107
    public $VendorSpecific;
108
    
109
    /**
110
     * A flag to preserve backwards compatibility for eduroamCAT application
111
     */
112
    public $eduroamCATcompatibility = false; 
113
    public $singleEAPProvider = false;
114
115
    private $eapId;
116
    private $namespace;
117
    private $providerInfo;
118
    private $authMethodsList;
119
    
120
    /**
121
     * create HTML code explaining the installer
122
     * 
123
     * @return string
124
     */
125
    public function writeDeviceInfo()
126
    {
127
        \core\common\Entity::intoThePotatoes();
128
        $out = "<p>";
129
        $out .= sprintf(_("This is a generic configuration file in the IETF <a href='%s'>EAP Metadata -00</a> XML format."), "https://tools.ietf.org/html/draft-winter-opsawg-eap-metadata-00");
130
        \core\common\Entity::outOfThePotatoes();
131
        return $out;
132
    }
133
134
    /**
135
     * create the actual XML file
136
     * 
137
     * @return string filename of the generated installer
138
     * @throws Exception
139
     *
140
     */
141
    public function writeInstaller()
142
    {
143
        \core\common\Entity::intoThePotatoes();
144
        $rootname = 'EAPIdentityProviderList';
145
        $dom = new \DOMDocument('1.0', 'utf-8');
146
        $root = $dom->createElement($rootname);
147
        $dom->appendChild($root);
148
        $ns = $dom->createAttributeNS( 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:noNamespaceSchemaLocation' );
149
        $ns->value = "eap-metadata.xsd";
150
        $root->appendChild($ns);
151
        $this->openRoamingToU = sprintf(_("I have read and agree to OpenRoaming Terms of Use at %s."), "https://wballiance.com/openroaming/toc-2020/");
152
        foreach ($this->languageInstance->getAllTranslations("I have read and agree to OpenRoaming Terms of Use at %s", "device") as $lang => $message) {
153
            $this->openRoamingToUArray[$lang] = sprintf($message, "https://wballiance.com/openroaming/toc-2020/");
154
        }
155
        
156
        if (empty($this->attributes['internal:realm'][0])) {
157
            $this->eapId = 'undefined';
158
            $this->namespace = 'urn:undefined';
159
        } else {
160
            $this->eapId = $this->attributes['internal:realm'][0];
161
            $this->namespace = 'urn:RFC4282:realm';
162
        }
163
        
164
        $this->authMethodsList = $this->getAuthMethodsList();
165
        $this->loggerInstance->debug(5, $this->attributes['internal:networks'], "NETWORKS:", "\n");
166
        /*
167
         * This approach is forced by geteduroam compatibility. We pack all networks into a single Provider
168
         * with the exception of the openroaming one which we pack separately.
169
         */
170
        
171
        if ($this->singleEAPProvider === true) {
172
            /*
173
             * if "condition" is set to openroaming, OpenRoaming terms of use must be mentioned
174
             * unless the preagreed is set for openroaming
175
             * if "ask" is set then we generate a separate OR profile which needs to contain the OR ToU
176
             * the ToU is not needed in the eduroam-only profile
177
             */
178
            $ssids = [];
179
            $ois = [];
180
            $orNetwork = [];
181
            foreach ($this->attributes['internal:networks'] as $netName => $netDefinition) {
182
                if ($netDefinition['condition'] === 'internal:openroaming' &&
183
                        $this->attributes['internal:openroaming']) {
184
                    $this->setORtou();
185
                    if (preg_match("/^ask/",$this->attributes['media:openroaming'][0])) {
186
                        $orNetwork = $netDefinition;
187
                        continue;                        
188
                    }
189
                }
190
                foreach ($netDefinition['ssid'] as $ssid) {
191
                    $ssids[] = $ssid;
192
                }
193
                foreach ($netDefinition['oi'] as $oi) {
194
                    $ois[] = $oi;
195
                }
196
            }
197
198
            if (!empty($orNetwork)) {
199
                $this->addORtou = false;
200
            }
201
            $this->providerInfo = $this->getProviderInfo();
202
            
203
            if (!empty($ssids) || !empty($ois)) {
204
                \core\DeviceXMLmain::marshalObject($dom, $root, 'EAPIdentityProvider', $this->eapIdp($ssids, $ois));
205
            }
206
            
207
            if (!empty($orNetwork)) {
208
                // here we need to add the Tou unless preagreed is set
209
                $this->setORtou();
210
                $this->providerInfo = $this->getProviderInfo();
211
                \core\DeviceXMLmain::marshalObject($dom, $root, 'EAPIdentityProvider', $this->eapIdp($orNetwork['ssid'], $orNetwork['oi']));
212
            }
213
        } else {
214
215
            foreach ($this->attributes['internal:networks'] as $netName => $netDefinition) {
216
                if ($netDefinition['condition'] === 'internal:openroaming' &&
217
                        $this->attributes['internal:openroaming']) {
218
                    $this->setORtou();
219
                } else {
220
                    $this->addORtou = false;
221
                }
222
                $this->providerInfo = $this->getProviderInfo();
223
                $ssids = $netDefinition['ssid'];
224
                $ois = $netDefinition['oi'];
225
                if (!empty($ssids) || !empty($ois)) {
226
                    \core\DeviceXMLmain::marshalObject($dom, $root, 'EAPIdentityProvider', $this->eapIdp($ssids, $ois));
227
                }
228
            }
229
        }
230
        
231
        if ($dom->schemaValidate(ROOT.'/devices/eap_config/eap-metadata.xsd') === FALSE) {
232
            throw new Exception("Schema validation failed for eap-metadata");
233
        }
234
235
        $dom->formatOutput = true;
236
        file_put_contents($this->installerBasename.'.eap-config', $dom->saveXML($dom));
237
        \core\common\Entity::outOfThePotatoes();
238
        return($this->installerBasename.'.eap-config');
239
    }
240
    
241
    private function setORtou() {
242
        if (preg_match("/preagreed/",$this->attributes['media:openroaming'][0])) {
243
            $this->addORtou = false;
244
        } else {
245
            $this->addORtou = true;
246
        }
247
    }
248
    
249
    /**
250
     * determines the inner authentication. Is it EAP, and which mechanism is used to convey actual auth data
251
     * @param array $eap the EAP type for which we want to get the inner auth
252
     * @return array
253
     */    
254
    private function eapIdp($ssids, $oids)
255
    {
256
        $eapIdp = new \core\DeviceXMLmain();
257
        $eapIdp->setAttribute('version', '1');
258
        if ($this->langScope === 'single') {
259
            $eapIdp->setAttribute('lang', $this->languageInstance->getLang());
260
        }
261
        $eapIdp->setAttribute('ID', $this->eapId);
262
        $eapIdp->setAttribute('namespace', $this->namespace);
263
        $authMethods = new \core\DeviceXMLmain();
264
        $authMethods->setChild('AuthenticationMethod', $this->authMethodsList);
265
        $eapIdp->setChild('AuthenticationMethods', $authMethods);
266
        $eapIdp->setChild('CredentialApplicability', $this->getCredentialApplicability($ssids,$oids));
267
// TODO   $eap_idp->setChild('ValidUntil',$this->getValidUntil());
268
        $eapIdp->setChild('ProviderInfo', $this->providerInfo);
269
// TODO   $eap_idp->setChild('VendorSpecific',$this->getVendorSpecific());
270
        return($eapIdp);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $eapIdp returns the type core\DeviceXMLmain which is incompatible with the documented return type array.
Loading history...
271
    }
272
273
    /**
274
     * determines the inner authentication. Is it EAP, and which mechanism is used to convey actual auth data
275
     * @param array $eap the EAP type for which we want to get the inner auth
276
     * @return array
277
     */  
278
    private function innerAuth($eap)
279
    {
280
        $out = [];
281
        $out['EAP'] = 0;
282
        switch ($eap["INNER"]) {
283
            case \core\common\EAP::NE_MSCHAP2:
284
                if ($this->eduroamCATcompatibility === TRUE) {
285
                    $out['METHOD'] = \core\common\EAP::MSCHAP2;
286
                    $out['EAP'] = 1;
287
                } else {
288
                    $out['METHOD'] = $eap["INNER"];
289
                }
290
                break;
291
            case \core\common\EAP::NE_SILVERBULLET:
292
                $out['METHOD'] = \core\common\EAP::NONE;
293
                break;
294
            default:
295
                $out['METHOD'] = $eap["INNER"];
296
                break;
297
        }
298
        // override if there is an inner EAP
299
        if ($eap["INNER"] > 0) { // there is an inner EAP method
300
            $out['EAP'] = 1;
301
        }
302
        return $out;
303
    }
304
    
305
    /**
306
     * 
307
     * @param string $attrName the attribute name
308
     * @return array of values for this attribute
309
     */
310
    private function getSimpleMLAttribute($attrName)
311
    {
312
        if (empty($this->attributes[$attrName][0])) {
313
            return([]);
314
        }
315
        $attributeList = $this->attributes[$attrName];
316
        $objs = [];
317
        if ($this->langScope === 'global') {
318
            foreach ($attributeList['langs'] as $language => $value) {
319
                $language = ($language === 'C' ? 'any' : $language);
320
                $obj = new \core\DeviceXMLmain();
321
                $obj->setValue($value);
322
                $obj->setAttributes(['lang' => $language]);
323
                $objs[] = $obj;
324
            }
325
        } else {
326
            $objs[] = $attributeList[0];
327
        }
328
        return($objs);
329
    }
330
    
331
    /**
332
     * constructs the name of the institution and puts it into the XML.
333
     * consists of the best-language-match inst name, and if the inst has more 
334
     * than one profile also the best-language-match profile name
335
     * 
336
     * @return \core\DeviceXMLmain[]
337
     */
338
    private function getDisplayName()
339
    {
340
        $attr = $this->attributes;
341
        $objs = [];
342
        if ($this->langScope === 'global') {
343
            $instNameLangs = $attr['general:instname']['langs'];
344
            if ($attr['internal:profile_count'][0] > 1) {
345
                $profileNameLangs = $attr['profile:name']['langs'];
346
            }
347
            foreach ($instNameLangs as $language => $value) {
348
                $language = ($language === 'C' ? 'any' : $language);
349
                $displayname = new \core\DeviceXMLmain();
350
                if (isset($profileNameLangs)) {
351
                    $langOrC = isset($profileNameLangs[$language]) ? $profileNameLangs[$language] : $profileNameLangs['C'];
352
                    $value .= ' - '.$langOrC;
353
                }
354
                $displayname->setValue($value);
355
                $displayname->setAttributes(['lang' => $language]);
356
                $objs[] = $displayname;
357
            }
358
        } else {
359
            $displayname = new \core\DeviceXMLmain();
360
            $value = $attr['general:instname'][0];
361
            if ($attr['internal:profile_count'][0] > 1) {
362
                $value .= ' - '.$attr['profile:name'][0];
363
            }
364
            $displayname->setValue($value);
365
            $objs[] = $displayname;
366
        }
367
        return $objs;
368
    }
369
370
    /**
371
     * retrieves the provider logo and puts it into the XML structure
372
     * 
373
     * @return \core\DeviceXMLmain
374
     */
375
    private function getProviderLogo()
376
    {
377
        $attr = $this->attributes;
378
        if (isset($attr['general:logo_file'][0])) {
379
            $logoString = base64_encode($attr['general:logo_file'][0]);
380
            $logoMime = 'image/'.$attr['internal:logo_file'][0]['mime'];
381
            $providerlogo = new \core\DeviceXMLmain();
382
            $providerlogo->setAttributes(['mime' => $logoMime, 'encoding' => 'base64']);
383
            $providerlogo->setValue($logoString);
384
            return $providerlogo;
385
        }
386
        return NULL;
387
    }
388
389
    /**
390
     * retrieves provider information and puts it into the XML structure.
391
     * contains the profile description and the ToU file, if any
392
     * 
393
     * @return \core\DeviceXMLmain
394
     */
395
    private function getProviderInfo()
396
    {
397
        $providerinfo = new \core\DeviceXMLmain();
398
        $providerinfo->setChild('DisplayName', $this->getDisplayName());
399
        $providerinfo->setChild('Description', $this->getSimpleMLAttribute('profile:description'));
400
        $providerinfo->setChild('ProviderLocation', $this->getProviderLocation());
401
        $providerinfo->setChild('ProviderLogo', $this->getProviderLogo());
402
        $providerinfo->setChild('TermsOfUse', $this->getProviderTou(), null, 'cdata');
403
        $providerinfo->setChild('Helpdesk', $this->getHelpdesk());
404
        return $providerinfo; 
405
    }
406
    
407
    private function getProviderTou() {
408
        $standardTou = $this->getSimpleMLAttribute('support:info_file');
409
        if ($this->addORtou === false) {
410
            return $standardTou;
411
        }
412
        $out = [];
413
        if ($this->langScope === 'global') {
414
            foreach ($standardTou as $touObj) {
415
                $tou = $touObj->getValue();
416
                $lngAttr = $touObj->getAttributes();
417
                $lng = $lngAttr['lang'] === 'any' ? \config\Master::APPEARANCE['defaultlocale'] : $lngAttr['lang'];
418
                $tou .= "\n".$this->openRoamingToUArray[$lng];
419
                $touObj->setValue($tou);
420
                $out[] =  $touObj;
421
            } 
422
        } else {
423
            $tou = $standardTou[0];
424
            $tou .= "\n".$this->openRoamingToU;
425
            $out = [$tou];
426
        }
427
        return $out;
428
    }
429
430
    /**
431
     * retrieves the location information and puts it into the XML structure
432
     * 
433
     * @return \core\DeviceXMLmain[]
434
     */
435
    private function getProviderLocation()
436
    {
437
        $attr = $this->attributes;
438
        if (isset($attr['general:geo_coordinates'])) {
439
            $attrCoordinates = $attr['general:geo_coordinates'];
440
            $location = [];
441
            foreach ($attrCoordinates as $a) {
442
                $providerlocation = new \core\DeviceXMLmain();
443
                $b = json_decode($a, true);
444
                $providerlocation->setChild('Longitude', $b['lon']);
445
                $providerlocation->setChild('Latitude', $b['lat']);
446
                $location[] = $providerlocation;
447
            }           
448
            return $location;
449
        }
450
        return NULL;
451
    }
452
453
    /**
454
     * retrieves helpdesk contact information and puts it into the XML structure
455
     * 
456
     * @return \core\DeviceXMLmain
457
     */
458
    private function getHelpdesk()
459
    {
460
        $helpdesk = new \core\DeviceXMLmain();
461
        $helpdesk->setChild('EmailAddress', $this->getSimpleMLAttribute('support:email'));
462
        $helpdesk->setChild('WebAddress', $this->getSimpleMLAttribute('support:url'));
463
        $helpdesk->setChild('Phone', $this->getSimpleMLAttribute('support:phone'));
464
        return $helpdesk;
465
    }
466
467
    /**
468
     * determine where this credential should be applicable
469
     * 
470
     * @return \core\DeviceXMLmain
471
     */
472
    private function getCredentialApplicability($ssids, $oids)
473
    {
474
        $setWired = isset($this->attributes['media:wired'][0]) && 
475
                $this->attributes['media:wired'][0] == 'on' ? 1 : 0;        
476
        $credentialapplicability = new \core\DeviceXMLmain();
477
        $ieee80211s = [];
478
        foreach ($ssids as $ssid) {
479
            $ieee80211 = new \core\DeviceXMLmain();
480
            $ieee80211->setChild('SSID', $ssid);
481
            $ieee80211->setChild('MinRSNProto', 'CCMP');
482
            $ieee80211s[] = $ieee80211;
483
        }
484
        foreach ($oids as $oid) {
485
            $ieee80211 = new \core\DeviceXMLmain();
486
            $ieee80211->setChild('ConsortiumOID', $oid);
487
            $ieee80211s[] = $ieee80211;
488
        }
489
        $credentialapplicability->setChild('IEEE80211', $ieee80211s);
490
        if ($setWired) {
491
            $credentialapplicability->setChild('IEEE8023', '');
492
        }
493
        return $credentialapplicability;
494
    }
495
496
    /**
497
     * retrieves the parameters needed for the given EAP method and creates
498
     * appropriate nodes in the XML structure for them
499
     * 
500
     * @param array $eap the EAP type in question
501
     * @return array a recap of the findings
502
     */
503
    private function getAuthenticationMethodParams($eap)
504
    {
505
        $inner = $this->innerAuth($eap);
506
        $outerMethod = $eap["OUTER"];
507
508
        if (isset($inner["METHOD"]) && $inner["METHOD"]) {
509
            $innerauthmethod = new \core\DeviceXMLmain();
510
            $typeOfInner = ($inner["EAP"] ? 'EAPMethod' : 'NonEAPAuthMethod');
511
            $eapmethod = new \core\DeviceXMLmain();
512
            $eapmethod->setChild('Type', abs($inner['METHOD']));
513
            $innerauthmethod->setChild($typeOfInner, $eapmethod);
514
            return ['inner_method' => $innerauthmethod, 'methodID' => $outerMethod, 'inner_methodID' => $inner['METHOD']];
515
        } else {
516
            return ['inner_method' => 0, 'methodID' => $outerMethod, 'inner_methodID' => 0];
517
        }
518
    }
519
520
    /**
521
     * sets the server-side credentials for a given EAP type
522
     * 
523
     * @param \devices\XML\Type $eaptype the EAP type
0 ignored issues
show
The type devices\XML\Type was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
524
     * @return \core\DeviceXMLmain
525
     */
526
    private function getServerSideCredentials($eap)
527
    {
528
        $attr = $this->attributes;
529
        $children = $this->authMethodElements['server'][$eap];
530
        $serversidecredential = new \core\DeviceXMLmain();
531
// Certificates and server names
532
        $cAlist = [];
533
        $attrCaList = $attr['internal:CAs'][0];
534
        foreach ($attrCaList as $ca) {
535
            $caObject = new \core\DeviceXMLmain();
536
            $caObject->setValue(base64_encode($ca['der']));
537
            $caObject->setAttributes(['format' => 'X.509', 'encoding' => 'base64']);
538
            $cAlist[] = $caObject;
539
        }
540
        $serverids = [];
541
        $servers = $attr['eap:server_name'];
542
        foreach ($servers as $server) {
543
            $serverid = new \core\DeviceXMLmain();
544
            $serverid->setValue($server);
545
            $serverids[] = $serverid;
546
        }
547
        if (in_array('CA', $children)) {
548
            $serversidecredential->setChild('CA', $cAlist);
549
        }
550
        if (in_array('ServerID', $children)) {
551
            $serversidecredential->setChild('ServerID', $serverids);
552
        }
553
        return $serversidecredential;
554
    }
555
556
    /**
557
     * sets the realm information for the client-side credential
558
     * 
559
     * @param \core\DeviceXMLmain $clientsidecredential the ClientSideCredential to which the realm info is to be added
560
     * @return void
561
     */
562
    private function setClientSideRealm($clientsidecredential)
563
    {
564
        $attr = $this->attributes;
565
        $realm = \core\common\Entity::getAttributeValue($attr, 'internal:realm', 0);
566
        if ($realm === NULL) {
567
            return;
568
        }
569
        if (\core\common\Entity::getAttributeValue($attr, 'internal:verify_userinput_suffix', 0) !== 1) {
570
            return;
571
        }
572
        $clientsidecredential->setChild('InnerIdentitySuffix', $realm);
573
        if (\core\common\Entity::getAttributeValue($attr, 'internal:hint_userinput_suffix', 0) === 1) {
574
            $clientsidecredential->setChild('InnerIdentityHint', 'true');
575
        }
576
    }
577
578
    /**
579
     * sets the client certificate
580
     * 
581
     * @return \core\DeviceXMLmain
582
     */
583
    private function getClientCertificate()
584
    {
585
        $clientCertificateObject = new \core\DeviceXMLmain();
586
        $clientCertificateObject->setValue(base64_encode($this->clientCert["certdata"]));
587
        $clientCertificateObject->setAttributes(['format' => 'PKCS12', 'encoding' => 'base64']);
588
        return $clientCertificateObject;
589
    }
590
591
    /**
592
     * sets the client-side credentials for the given EAP type
593
     * 
594
     * @param array $eapParams the EAP parameters
595
     * @return \core\DeviceXMLmain
596
     */
597
    private function getClientSideCredentials($eap)
598
    {
599
        $children = $this->authMethodElements['client'][$eap];
600
        $clientsidecredential = new \core\DeviceXMLmain();
601
        $outerId = $this->determineOuterIdString();
602
        $this->loggerInstance->debug(5, $eap, "XMLOI:", "\n");
603
        if (in_array('OuterIdentity', $children)) {
604
            if ($outerId !== NULL) {
605
                $clientsidecredential->setChild('OuterIdentity', $outerId);
606
            }
607
        }
608
        $this->setClientSideRealm($clientsidecredential);
609
//        $clientsidecredential->setChild('EAPType', $eapParams['inner_methodID'] ? $eapParams['inner_methodID'] : $eapParams['methodID']);
610
611
        // Client Certificate
612
        if ($this->selectedEap == \core\common\EAP::EAPTYPE_SILVERBULLET) {
613
            $attr = $this->attributes;
614
            $outerId = \core\common\Entity::getAttributeValue($attr, 'internal:username', 0);
615
            $clientsidecredential->setChild('OuterIdentity', $outerId);
616
            $clientsidecredential->setChild('ClientCertificate', $this->getClientCertificate());
617
        }
618
        return $clientsidecredential;
619
    }
620
621
    /**
622
     * sets the EAP method
623
     * 
624
     * @param \devices\XML\Type $eaptype the EAP type XMLObject
625
     * @return \core\DeviceXMLmain
626
     */
627
    private function getEapMethod($eaptype)
628
    {
629
        $eapmethod = new \core\DeviceXMLmain();
630
        $eapmethod->setChild('Type', $eaptype);
631
        if (isset($this->VendorSpecific)) {
632
            $vendorspecifics = [];
633
            foreach ($this->VendorSpecific as $vs) {
634
                $vendorspecific = new \core\DeviceXMLmain();
635
                $vs['value']->addAttribute('xsi:noNamespaceSchemaLocation', "xxx.xsd");
636
                $vendorspecific->setValue($vs['value']);
637
                $vendorspecific->setAttributes(['vendor' => $vs['vendor']]);
638
                $vendorspecifics[] = $vendorspecific;
639
            }
640
            $eapmethod->setChild('VendorSpecific', $vendorspecifics);
641
        }
642
        return($eapmethod);
643
    }
644
645
    /**
646
     * determines the authentication method to use
647
     * 
648
     * @param array $eap the EAP methods, in array representation
649
     * @return \core\DeviceXMLmain
650
     */
651
    private function getAuthMethod($eap)
652
    {
653
        $authmethod = new \core\DeviceXMLmain();
654
        $eapParams = $this->getAuthenticationMethodParams($eap);
655
        $eaptype = new \core\DeviceXMLmain();
656
        $eaptype->setValue($eapParams['methodID']);
657
// Type
658
        $authmethod->setChild('EAPMethod', $this->getEapMethod($eaptype));
659
660
// ServerSideCredentials
661
        $authmethod->setChild('ServerSideCredential', $this->getServerSideCredentials($eap['OUTER']));
662
663
// ClientSideCredentials
664
        $authmethod->setChild('ClientSideCredential', $this->getClientSideCredentials($eap['INNER']));
665
666
        if ($eapParams['inner_method']) {
667
            $authmethod->setChild('InnerAuthenticationMethod', $eapParams['inner_method']);
668
        }
669
        return $authmethod;
670
    }
671
    
672
    private function getAuthMethodsList() {
673
        $methodList = [];
674
        if ($this->allEaps) {
675
            $eapmethods = [];
676
            foreach ($this->attributes['all_eaps'] as $eap) {
677
                $eapRep = $eap->getArrayRep();
678
                if (in_array($eapRep, $this->supportedEapMethods)) {
679
                    $eapmethods[] = $eapRep;
680
                }
681
            }
682
        } else {
683
            $eapmethods = [$this->selectedEap];
684
        }
685
        foreach ($eapmethods as $eap) {
686
            $methodList[] = $this->getAuthMethod($eap);
687
        }
688
        return $methodList;
689
    }
690
    
691
    private $openRoamingToUArray;
692
    private $openRoamingToU;
693
    private $addORtou = false;
694
695
}
696