Passed
Push — master ( a910b7...d64176 )
by Tomasz
07:06
created

DeviceXML::setClientSideRealm()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 9
c 1
b 0
f 0
dl 0
loc 13
rs 9.9666
cc 4
nc 4
nop 1
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 fuction of the extenstions 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
        ]
73
    ];
74
75
    /**
76
     * construct the device
77
     */
78
    public function __construct()
79
    {
80
        parent::__construct();
81
    }
82
83
    /**
84
     * $langScope can be 'global' when all lang and all lang-specific information
85
     * is dumped or 'single' when only the selected lang (and defaults) are passed
86
     * NOTICE: 'global' is not yet supported
87
     * 
88
     * @var string
89
     */
90
    public $langScope;
91
92
    /**
93
     * whether all EAP types should be included in the file or only the 
94
     * preferred one
95
     * 
96
     * @var boolean
97
     */
98
    public $allEaps = FALSE;
99
100
    /**
101
     * vendor-specific additional information, this is nit yest fully
102
     * implemented due to lack of use cases.
103
     * 
104
     * @var array
105
     */
106
    public $VendorSpecific;
107
108
    /**
109
     * create HTML code explaining the installer
110
     * 
111
     * @return string
112
     */
113
    public function writeDeviceInfo()
114
    {
115
        \core\common\Entity::intoThePotatoes();
116
        $out = "<p>";
117
        $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");
118
        \core\common\Entity::outOfThePotatoes();
119
        return $out;
120
    }
121
122
    /**
123
     * create the actual XML file
124
     * 
125
     * @return string filename of the generated installer
126
     * @throws Exception
127
     *
128
     */
129
    public function writeInstaller()
130
    {
131
        \core\common\Entity::intoThePotatoes();
132
        $eapIdp = new \core\DeviceXMLmain();
133
        $eapIdp->setAttribute('version', '1');
134
        if ($this->langScope === 'single') {
135
            $eapIdp->setAttribute('lang', $this->languageInstance->getLang());
136
        }
137
        if (empty($this->attributes['internal:realm'][0])) {
138
            $eapIdp->setAttribute('ID', 'undefined');
139
            $namespace = 'urn:undefined';
140
        } else {
141
            $eapIdp->setAttribute('ID', $this->attributes['internal:realm'][0]);
142
            $namespace = 'urn:RFC4282:realm';
143
        }
144
        $eapIdp->setAttribute('namespace', $namespace);
145
        $authMethods = new \core\DeviceXMLmain();
146
        $authMethods->setChild('AuthenticationMethod', $this->getAuthMethodsList());
147
        $eapIdp->setChild('AuthenticationMethods', $authMethods);       
148
        $eapIdp->setChild('CredentialApplicability', $this->getCredentialApplicability());
149
// TODO   $eap_idp->setChild('ValidUntil',$this->getValidUntil());
150
        $eapIdp->setChild('ProviderInfo', $this->getProviderInfo());
151
// TODO   $eap_idp->setChild('VendorSpecific',$this->getVendorSpecific());
152
153
// Generate XML
154
        $rootname = 'EAPIdentityProviderList';
155
        $root = new \SimpleXMLElement("<?xml version=\"1.0\" encoding=\"utf-8\" ?><{$rootname} xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"eap-metadata.xsd\"></{$rootname}>");
156
        \core\DeviceXMLmain::marshalObject($root, 'EAPIdentityProvider', $eapIdp);
157
        $dom = dom_import_simplexml($root)->ownerDocument;
158
        if ($dom->schemaValidate(ROOT.'/devices/eap_config/eap-metadata.xsd') === FALSE) {
159
            throw new Exception("Schema validation failed for eap-metadata");
160
        }
161
        $dom->formatOutput = true;
162
        file_put_contents($this->installerBasename.'.eap-config', $dom->saveXML());
163
        \core\common\Entity::outOfThePotatoes();
164
        return($this->installerBasename.'.eap-config');
165
    }
166
167
168
    /**
169
     * determines the inner authentication. Is it EAP, and which mechanism is used to convey actual auth data
170
     * @param array $eap the EAP type for which we want to get the inner auth
171
     * @return array
172
     */
173
    private function innerAuth($eap)
174
    {
175
        $out = [];
176
        $out['EAP'] = 0;
177
        // this is a hack - eduroamCAT does not handle NE_MSCHAP2 however
178
        // treats the inner NE_MSCHAP2 correctly wheb set to the EAP type
179
        switch ($eap["INNER"]) {
180
            case \core\common\EAP::NE_MSCHAP2:
181
                $out['METHOD'] = \core\common\EAP::MSCHAP2;
182
                $out['EAP'] = 1;
183
                break;
184
            case \core\common\EAP::NE_SILVERBULLET:
185
                $out['METHOD'] = \core\common\EAP::NONE;
186
                break;
187
            default:
188
                $out['METHOD'] = $eap["INNER"];
189
                break;
190
        }
191
        // override if there is an inner EAP
192
        if ($eap["INNER"] > 0) { // there is an inner EAP method
193
            $out['EAP'] = 1;
194
        }
195
        return $out;
196
    }
197
    
198
    /**
199
     * 
200
     * @param string $attrName the attribute name
201
     * @return array of values for this attribute
202
     */
203
    private function getSimpleMLAttribute($attrName)
204
    {
205
        if (empty($this->attributes[$attrName][0])) {
206
            return([]);
207
        }
208
        $attributeList = $this->attributes[$attrName];
209
        $objs = [];
210
        if ($this->langScope === 'global') {
211
            foreach ($attributeList['langs'] as $language => $value) {
212
                $language = ($language === 'C' ? 'any' : $language);
213
                $obj = new \core\DeviceXMLmain();
214
                $obj->setValue($value);
215
                $obj->setAttributes(['lang' => $language]);
216
                $objs[] = $obj;
217
            }
218
        } else {
219
            $objs[] = $attributeList[0];
220
        }
221
        return($objs);
222
    }
223
224
    /**
225
     * constructs the name of the institution and puts it into the XML.
226
     * consists of the best-language-match inst name, and if the inst has more 
227
     * than one profile also the best-language-match profile name
228
     * 
229
     * @return \core\DeviceXMLmain[]
230
     */
231
    private function getDisplayName()
232
    {
233
        $attr = $this->attributes;
234
        $objs = [];
235
        if ($this->langScope === 'global') {
236
            $instNameLangs = $attr['general:instname']['langs'];
237
            if ($attr['internal:profile_count'][0] > 1) {
238
                $profileNameLangs = $attr['profile:name']['langs'];
239
            }
240
            foreach ($instNameLangs as $language => $value) {
241
                $language = ($language === 'C' ? 'any' : $language);
242
                $displayname = new \core\DeviceXMLmain();
243
                if (isset($profileNameLangs)) {
244
                    $langOrC = isset($profileNameLangs[$language]) ? $profileNameLangs[$language] : $profileNameLangs['C'];
245
                    $value .= ' - '.$langOrC;
246
                }
247
                $displayname->setValue($value);
248
                $displayname->setAttributes(['lang' => $language]);
249
                $objs[] = $displayname;
250
            }
251
        } else {
252
            $displayname = new \core\DeviceXMLmain();
253
            $value = $attr['general:instname'][0];
254
            if ($attr['internal:profile_count'][0] > 1) {
255
                $value .= ' - '.$attr['profile:name'][0];
256
            }
257
            $displayname->setValue($value);
258
            $objs[] = $displayname;
259
        }
260
        return $objs;
261
    }
262
263
    /**
264
     * retrieves the provider logo and puts it into the XML structure
265
     * 
266
     * @return \core\DeviceXMLmain
267
     */
268
    private function getProviderLogo()
269
    {
270
        $attr = $this->attributes;
271
        if (isset($attr['general:logo_file'][0])) {
272
            $logoString = base64_encode($attr['general:logo_file'][0]);
273
            $logoMime = 'image/'.$attr['internal:logo_file'][0]['mime'];
274
            $providerlogo = new \core\DeviceXMLmain();
275
            $providerlogo->setAttributes(['mime' => $logoMime, 'encoding' => 'base64']);
276
            $providerlogo->setValue($logoString);
277
            return $providerlogo;
278
        }
279
        return NULL;
280
    }
281
282
    /**
283
     * retrieves provider information and puts it into the XML structure.
284
     * contains the profile description and the ToU file, if any
285
     * 
286
     * @return \core\DeviceXMLmain
287
     */
288
    private function getProviderInfo()
289
    {
290
        $providerinfo = new \core\DeviceXMLmain();
291
        $providerinfo->setChild('DisplayName', $this->getDisplayName());
292
        $providerinfo->setChild('Description', $this->getSimpleMLAttribute('profile:description'));
293
        $providerinfo->setChild('ProviderLocation', $this->getProviderLocation());
294
        $providerinfo->setChild('ProviderLogo', $this->getProviderLogo());
295
        $providerinfo->setChild('TermsOfUse', $this->getSimpleMLAttribute('support:info_file'));
296
        $providerinfo->setChild('Helpdesk', $this->getHelpdesk());
297
        return $providerinfo;
298
    }
299
300
    /**
301
     * retrieves the location information and puts it into the XML structure
302
     * 
303
     * @return \core\DeviceXMLmain[]
304
     */
305
    private function getProviderLocation()
306
    {
307
        $attr = $this->attributes;
308
        if (isset($attr['general:geo_coordinates'])) {
309
            $attrCoordinates = $attr['general:geo_coordinates'];
310
            $location = [];
311
            foreach ($attrCoordinates as $a) {
312
                $providerlocation = new \core\DeviceXMLmain();
313
                $b = json_decode($a, true);
314
                $providerlocation->setChild('Longitude', $b['lon']);
315
                $providerlocation->setChild('Latitude', $b['lat']);
316
                $location[] = $providerlocation;
317
            }           
318
            return $location;
319
        }
320
        return NULL;
321
    }
322
323
    /**
324
     * retrieves helpdesk contact information and puts it into the XML structure
325
     * 
326
     * @return \core\DeviceXMLmain
327
     */
328
    private function getHelpdesk()
329
    {
330
        $helpdesk = new \core\DeviceXMLmain();
331
        $helpdesk->setChild('EmailAddress', $this->getSimpleMLAttribute('support:email'));
332
        $helpdesk->setChild('WebAddress', $this->getSimpleMLAttribute('support:url'));
333
        $helpdesk->setChild('Phone', $this->getSimpleMLAttribute('support:phone'));
334
        return $helpdesk;
335
    }
336
337
    /**
338
     * determine where this credential should be applicable
339
     * 
340
     * @return \core\DeviceXMLmain
341
     */
342
    private function getCredentialApplicability()
343
    {
344
        $ssids = $this->attributes['internal:SSID'];
345
        $oids = $this->attributes['internal:consortia'];
346
        $credentialapplicability = new \core\DeviceXMLmain();
347
        $ieee80211s = [];
348
        foreach ($ssids as $ssid => $ciph) {
349
            $ieee80211 = new \core\DeviceXMLmain();
350
            $ieee80211->setChild('SSID', $ssid);
351
            $ieee80211->setChild('MinRSNProto', $ciph == 'AES' ? 'CCMP' : 'TKIP');
352
            $ieee80211s[] = $ieee80211;
353
        }
354
        foreach ($oids as $oid) {
355
            $ieee80211 = new \core\DeviceXMLmain();
356
            $ieee80211->setChild('ConsortiumOID', $oid);
357
            $ieee80211s[] = $ieee80211;
358
        }
359
        $credentialapplicability->setChild('IEEE80211', $ieee80211s);
360
        return $credentialapplicability;
361
    }
362
363
    /**
364
     * retrieves the parameters needed for the given EAP method and creates
365
     * appropriate nodes in the XML structure for them
366
     * 
367
     * @param array $eap the EAP type in question
368
     * @return array a recap of the findings
369
     */
370
    private function getAuthenticationMethodParams($eap)
371
    {
372
        $inner = $this->innerAuth($eap);
373
        $outerMethod = $eap["OUTER"];
374
375
        if (isset($inner["METHOD"]) && $inner["METHOD"]) {
376
            $innerauthmethod = new \core\DeviceXMLmain();
377
            $typeOfInner = ($inner["EAP"] ? 'EAPMethod' : 'NonEAPAuthMethod');
378
            $eapmethod = new \core\DeviceXMLmain();
379
            $eapmethod->setChild('Type', abs($inner['METHOD']));
380
            $innerauthmethod->setChild($typeOfInner, $eapmethod);
381
            return ['inner_method' => $innerauthmethod, 'methodID' => $outerMethod, 'inner_methodID' => $inner['METHOD']];
382
        } else {
383
            return ['inner_method' => 0, 'methodID' => $outerMethod, 'inner_methodID' => 0];
384
        }
385
    }
386
387
    /**
388
     * sets the server-side credentials for a given EAP type
389
     * 
390
     * @param \devices\XML\Type $eaptype the EAP type
391
     * @return \core\DeviceXMLmain
392
     */
393
    private function getServerSideCredentials($eap)
394
    {
395
        $attr = $this->attributes;
396
        $children = $this->authMethodElements['server'][$eap];
397
        $serversidecredential = new \core\DeviceXMLmain();
398
// Certificates and server names
399
        $cAlist = [];
400
        $attrCaList = $attr['internal:CAs'][0];
401
        foreach ($attrCaList as $ca) {
402
            $caObject = new \core\DeviceXMLmain();
403
            $caObject->setValue(base64_encode($ca['der']));
404
            $caObject->setAttributes(['format' => 'X.509', 'encoding' => 'base64']);
405
            $cAlist[] = $caObject;
406
        }
407
        $serverids = [];
408
        $servers = $attr['eap:server_name'];
409
        foreach ($servers as $server) {
410
            $serverid = new \core\DeviceXMLmain();
411
            $serverid->setValue($server);
412
            $serverids[] = $serverid;
413
        }
414
        if (in_array('CA', $children)) {
415
            $serversidecredential->setChild('CA', $cAlist);
416
        }
417
        if (in_array('ServerID', $children)) {
418
            $serversidecredential->setChild('ServerID', $serverids);
419
        }
420
        return $serversidecredential;
421
    }
422
423
    /**
424
     * sets the realm information for the client-side credential
425
     * 
426
     * @param \devices\XML\ClientSideCredential $clientsidecredential the ClientSideCredential to which the realm info is to be added
427
     * @return void
428
     */
429
    private function setClientSideRealm($clientsidecredential)
430
    {
431
        $attr = $this->attributes;
432
        $realm = \core\common\Entity::getAttributeValue($attr, 'internal:realm', 0);
433
        if ($realm === NULL) {
434
            return;
435
        }
436
        if (\core\common\Entity::getAttributeValue($attr, 'internal:verify_userinput_suffix', 0) !== 1) {
437
            return;
438
        }
439
        $clientsidecredential->setChild('InnerIdentitySuffix', $realm);
0 ignored issues
show
Bug introduced by
The method setChild() does not exist on devices\xml\ClientSideCredential. ( Ignorable by Annotation )

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

439
        $clientsidecredential->/** @scrutinizer ignore-call */ 
440
                               setChild('InnerIdentitySuffix', $realm);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
440
        if (\core\common\Entity::getAttributeValue($attr, 'internal:hint_userinput_suffix', 0) === 1) {
441
            $clientsidecredential->setChild('InnerIdentityHint', 'true');
442
        }
443
    }
444
445
    /**
446
     * sets the client certificate
447
     * 
448
     * @return \core\DeviceXMLmain
449
     */
450
    private function getClientCertificate()
451
    {
452
        $clientCertificateObject = new \core\DeviceXMLmain();
453
        $clientCertificateObject->setValue(base64_encode($this->clientCert["certdata"]));
454
        $clientCertificateObject->setAttributes(['format' => 'PKCS12', 'encoding' => 'base64']);
455
        return $clientCertificateObject;
456
    }
457
458
    /**
459
     * sets the client-side credentials for the given EAP type
460
     * 
461
     * @param array $eapParams the EAP parameters
462
     * @return \core\DeviceXMLmain
463
     */
464
    private function getClientSideCredentials($eap)
465
    {
466
        $children = $this->authMethodElements['client'][$eap];
467
        $clientsidecredential = new \core\DeviceXMLmain();
468
        $outerId = $this->determineOuterIdString();
469
        $this->loggerInstance->debug(5, $eap, "XMLOI:", "\n");
470
        if (in_array('OuterIdentity', $children)) {
471
            if ($outerId !== NULL) {
472
                $clientsidecredential->setChild('OuterIdentity', $outerId);
473
            }
474
        }
475
        $this->setClientSideRealm($clientsidecredential);
0 ignored issues
show
Bug introduced by
$clientsidecredential of type core\DeviceXMLmain is incompatible with the type devices\XML\ClientSideCredential expected by parameter $clientsidecredential of devices\eap_config\DeviceXML::setClientSideRealm(). ( Ignorable by Annotation )

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

475
        $this->setClientSideRealm(/** @scrutinizer ignore-type */ $clientsidecredential);
Loading history...
476
//        $clientsidecredential->setChild('EAPType', $eapParams['inner_methodID'] ? $eapParams['inner_methodID'] : $eapParams['methodID']);
477
478
        // Client Certificate
479
        if ($this->selectedEap == \core\common\EAP::EAPTYPE_SILVERBULLET) {
480
            $attr = $this->attributes;
481
            $outerId = \core\common\Entity::getAttributeValue($attr, 'internal:username', 0);
482
            $clientsidecredential->setChild('OuterIdentity', $outerId);
483
            $clientsidecredential->setChild('ClientCertificate', $this->getClientCertificate());
484
        }
485
        return $clientsidecredential;
486
    }
487
488
    /**
489
     * sets the EAP method
490
     * 
491
     * @param \devices\XML\Type $eaptype the EAP type XMLObject
492
     * @return \core\DeviceXMLmain
493
     */
494
    private function getEapMethod($eaptype)
495
    {
496
        $eapmethod = new \core\DeviceXMLmain();
497
        $eapmethod->setChild('Type', $eaptype);
498
        if (isset($this->VendorSpecific)) {
499
            $vendorspecifics = [];
500
            foreach ($this->VendorSpecific as $vs) {
501
                $vendorspecific = new \core\DeviceXMLmain();
502
                $vs['value']->addAttribute('xsi:noNamespaceSchemaLocation', "xxx.xsd");
503
                $vendorspecific->setValue($vs['value']);
504
                $vendorspecific->setAttributes(['vendor' => $vs['vendor']]);
505
                $vendorspecifics[] = $vendorspecific;
506
            }
507
            $eapmethod->setChild('VendorSpecific', $vendorspecifics);
508
        }
509
        return($eapmethod);
510
    }
511
512
    /**
513
     * determines the authentication method to use
514
     * 
515
     * @param array $eap the EAP methods, in array representation
516
     * @return \core\DeviceXMLmain
517
     */
518
    private function getAuthMethod($eap)
519
    {
520
        $authmethod = new \core\DeviceXMLmain();
521
        $eapParams = $this->getAuthenticationMethodParams($eap);
522
        $eaptype = new \core\DeviceXMLmain();
523
        $eaptype->setValue($eapParams['methodID']);
524
// Type
525
        $authmethod->setChild('EAPMethod', $this->getEapMethod($eaptype));
0 ignored issues
show
Bug introduced by
$eaptype of type core\DeviceXMLmain is incompatible with the type devices\XML\Type expected by parameter $eaptype of devices\eap_config\DeviceXML::getEapMethod(). ( Ignorable by Annotation )

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

525
        $authmethod->setChild('EAPMethod', $this->getEapMethod(/** @scrutinizer ignore-type */ $eaptype));
Loading history...
526
527
// ServerSideCredentials
528
        $authmethod->setChild('ServerSideCredential', $this->getServerSideCredentials($eap['OUTER']));
529
530
// ClientSideCredentials
531
        $authmethod->setChild('ClientSideCredential', $this->getClientSideCredentials($eap['INNER']));
532
533
        if ($eapParams['inner_method']) {
534
            $authmethod->setChild('InnerAuthenticationMethod', $eapParams['inner_method']);
535
        }
536
        return $authmethod;
537
    }
538
    
539
    private function getAuthMethodsList() {
540
        $methodList = [];
541
        if ($this->allEaps) {
542
            $eapmethods = [];
543
            foreach ($this->attributes['all_eaps'] as $eap) {
544
                $eapRep = $eap->getArrayRep();
545
                if (in_array($eapRep, $this->supportedEapMethods)) {
546
                    $eapmethods[] = $eapRep;
547
                }
548
            }
549
        } else {
550
            $eapmethods = [$this->selectedEap];
551
        }
552
        foreach ($eapmethods as $eap) {
553
            $methodList[] = $this->getAuthMethod($eap);
554
        }
555
        return $methodList;
556
    }
557
558
559
560
}
561