Test Failed
Push — master ( 40bfca...a505f4 )
by Stefan
07:22 queued 11s
created

EAP::getArrayRep()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
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 contains the EAP class and some constants for EAP types.
25
 *
26
 * @author Stefan Winter <[email protected]>
27
 * @author Tomasz Wolniewicz <[email protected]>
28
 *
29
 * @package Developer
30
 * 
31
 */
32
33
namespace core\common;
34
35
use \Exception;
36
37
/**
38
 * Convenience functions for EAP types
39
 *
40
 * @author Stefan Winter <[email protected]>
41
 * @author Tomasz Wolniewicz <[email protected]>
42
 *
43
 * @license see LICENSE file in root directory
44
 *
45
 * @package Developer
46
 */
47
class EAP extends Entity
48
{
49
50
    /**
51
     * some EAP-related constants.
52
     */
53
    const PEAP = 25;
54
    const MSCHAP2 = 26;
55
    const TTLS = 21;
56
    const TLS = 13;
57
    const NONE = 0;
58
    const GTC = 6;
59
    const FAST = 43;
60
    const PWD = 52;
61
    const NE_PAP = -1;
62
    const NE_MSCHAP = -2;
63
    const NE_MSCHAP2 = -3;
64
    const NE_SILVERBULLET = -999;
65
    const INTEGER_TTLS_PAP = 1;
66
    const INTEGER_PEAP_MSCHAP2 = 2;
67
    const INTEGER_TLS = 3;
68
    const INTEGER_FAST_GTC = 4;
69
    const INTEGER_TTLS_GTC = 5;
70
    const INTEGER_TTLS_MSCHAP2 = 6;
71
    const INTEGER_EAP_PWD = 7;
72
    const INTEGER_SILVERBULLET = 8;
73
74
// PHP7 allows to define constants with arrays as value. Hooray! This makes
75
// lots of public static members of the EAP class obsolete
76
77
    /**
78
     * PEAP-MSCHAPv2: Outer EAP Type = 25, Inner EAP Type = 26
79
     */
80
    const EAPTYPE_PEAP_MSCHAP2 = ["OUTER" => EAP::PEAP, "INNER" => EAP::MSCHAP2];
81
82
    /**
83
     * EAP-TLS: Outer EAP Type = 13, no inner EAP
84
     */
85
    const EAPTYPE_TLS = ["OUTER" => EAP::TLS, "INNER" => EAP::NONE];
86
87
    /**
88
     * EAP-TLS: Outer EAP Type = 13, no inner EAP
89
     */
90
    const EAPTYPE_SILVERBULLET = ["OUTER" => EAP::TLS, "INNER" => EAP::NE_SILVERBULLET];
91
92
    /**
93
     * TTLS-PAP: Outer EAP type = 21, no inner EAP, inner non-EAP = 1
94
     */
95
    const EAPTYPE_TTLS_PAP = ["OUTER" => EAP::TTLS, "INNER" => EAP::NE_PAP];
96
97
    /**
98
     * TTLS-MSCHAP-v2: Outer EAP type = 21, no inner EAP, inner non-EAP = 3
99
     */
100
    const EAPTYPE_TTLS_MSCHAP2 = ["OUTER" => EAP::TTLS, "INNER" => EAP::NE_MSCHAP2];
101
102
    /**
103
     * TTLS-GTC: Outer EAP type = 21, Inner EAP Type = 6
104
     */
105
    const EAPTYPE_TTLS_GTC = ["OUTER" => EAP::TTLS, "INNER" => EAP::GTC];
106
107
    /**
108
     * EAP-FAST (GTC): Outer EAP type = 43, Inner EAP Type = 6
109
     */
110
    const EAPTYPE_FAST_GTC = ["OUTER" => EAP::FAST, "INNER" => EAP::GTC];
111
112
    /**
113
     * PWD: Outer EAP type = 52, no inner EAP
114
     */
115
    const EAPTYPE_PWD = ["OUTER" => EAP::PWD, "INNER" => EAP::NONE];
116
117
    /**
118
     * NULL: no outer EAP, no inner EAP
119
     */
120
    const EAPTYPE_NONE = ["OUTER" => EAP::NONE, "INNER" => EAP::NONE];
121
122
    /**
123
     *  ANY: not really an EAP method, but the term to use when needing to express "any EAP method we know"
124
     */
125
    const EAPTYPE_ANY = ["OUTER" => 255, "INNER" => 255];
126
127
    /**
128
     * conversion table between array and integer representations
129
     */
130
    const EAPTYPES_CONVERSION = [
131
        EAP::INTEGER_FAST_GTC => EAP::EAPTYPE_FAST_GTC,
132
        EAP::INTEGER_PEAP_MSCHAP2 => EAP::EAPTYPE_PEAP_MSCHAP2,
133
        EAP::INTEGER_EAP_PWD => EAP::EAPTYPE_PWD,
134
        EAP::INTEGER_TLS => EAP::EAPTYPE_TLS,
135
        EAP::INTEGER_TTLS_GTC => EAP::EAPTYPE_TTLS_GTC,
136
        EAP::INTEGER_TTLS_MSCHAP2 => EAP::EAPTYPE_TTLS_MSCHAP2,
137
        EAP::INTEGER_TTLS_PAP => EAP::EAPTYPE_TTLS_PAP,
138
        EAP::INTEGER_SILVERBULLET => EAP::EAPTYPE_SILVERBULLET,
139
    ];
140
141
    /**
142
     * The array representation of the EAP type
143
     * @var array
144
     */
145
    private $arrayRep;
146
147
    /**
148
     * The integer representation of the EAP type
149
     * @var integer
150
     */
151
    private $intRep;
152
153
    /**
154
     * Instantiates the EAP class for a concrete EAP type. Only call it to 
155
     * instantiate *real* EAP types, i.e. not EAPTYPE::ANY or EAPTYPE::NONE
156
     * 
157
     * @param mixed $eapType the EAP type, either in its integer or array representation
158
     * @throws Exception
159
     */
160
    public function __construct($eapType)
161
    {
162
        if (is_numeric($eapType) && array_key_exists($eapType, EAP::EAPTYPES_CONVERSION)) {
163
            $key = array_keys(EAP::EAPTYPES_CONVERSION, EAP::EAPTYPES_CONVERSION[$eapType]);
164
            $this->intRep = $key[0];
165
            $this->arrayRep = EAP::EAPTYPES_CONVERSION[$this->intRep];
166
            return;
167
        }
168
        if (is_array($eapType)) {
169
            $key = array_search($eapType, EAP::EAPTYPES_CONVERSION);
170
            if ($key !== FALSE) {
171
                // add a type cast to int to make Scrutinizer realise that the key found is always an integer
172
                $this->intRep = (int) $key; // array index is always an integer
173
                $this->arrayRep = EAP::EAPTYPES_CONVERSION[(int) $key];
174
                return;
175
            }
176
        }
177
        throw new Exception("Unable to instantiate the EAP class - the EAP type is bogus.");
178
    }
179
180
    /**
181
     * Is this a password-based EAP method?
182
     * @return boolean
183
     * @throws Exception
184
     */
185
    public function isPasswordRequired()
186
    {
187
        switch ($this->intRep) {
188
            case EAP::INTEGER_EAP_PWD:
189
            case EAP::INTEGER_FAST_GTC:
190
            case EAP::INTEGER_PEAP_MSCHAP2:
191
            case EAP::INTEGER_TTLS_GTC:
192
            case EAP::INTEGER_TTLS_MSCHAP2:
193
            case EAP::INTEGER_TTLS_PAP:
194
                return TRUE;
195
            case EAP::INTEGER_TLS:
196
            case EAP::INTEGER_SILVERBULLET:
197
                return FALSE;
198
            default:
199
                throw new Exception("Unable to determine if the EAP type required a password or not!");
200
        }
201
    }
202
203
    /**
204
     * There could be EAP methods which have an optional need for a password.
205
     * Not aware of any, so this is a simple function :-)
206
     * @return boolean
207
     */
208
    public function isPasswordOptional()
209
    {
210
        return FALSE;
211
    }
212
213
    /**
214
     * Is this a certificate-based EAP method?
215
     * @return boolean
216
     * @throws Exception
217
     */
218
    public function isClientCertRequired()
219
    {
220
        switch ($this->intRep) {
221
            case EAP::INTEGER_EAP_PWD:
222
            case EAP::INTEGER_FAST_GTC:
223
            case EAP::INTEGER_PEAP_MSCHAP2:
224
            case EAP::INTEGER_TTLS_GTC:
225
            case EAP::INTEGER_TTLS_MSCHAP2:
226
            case EAP::INTEGER_TTLS_PAP:
227
                return FALSE;
228
            case EAP::INTEGER_TLS:
229
            case EAP::INTEGER_SILVERBULLET:
230
                return TRUE;
231
            default:
232
                throw new Exception("Unable to determine if the EAP type requires client-certificates or not!");
233
        }
234
    }
235
236
    /**
237
     * Does an EAP type optionally allow to send a client certificate?
238
     * @return boolean
239
     * @throws Exception
240
     */
241
    public function isClientCertOptional()
242
    {
243
        switch ($this->intRep) {
244
            case EAP::INTEGER_EAP_PWD:
245
            case EAP::INTEGER_TLS:
246
            case EAP::INTEGER_SILVERBULLET:
247
                return FALSE;
248
            case EAP::INTEGER_FAST_GTC:
249
            case EAP::INTEGER_PEAP_MSCHAP2:
250
            case EAP::INTEGER_TTLS_GTC:
251
            case EAP::INTEGER_TTLS_MSCHAP2:
252
            case EAP::INTEGER_TTLS_PAP:
253
                return TRUE;
254
            default:
255
                throw new Exception("Unable to determine if the EAP type has optional client-certificates or not!");
256
        }
257
    }
258
259
    /**
260
     * Does the EAP type require the specification of trusted CAs to be secure?
261
     * @return boolean
262
     * @throws Exception
263
     */
264
    public function needsServerCACert()
265
    {
266
        switch ($this->intRep) {
267
            case EAP::INTEGER_EAP_PWD:
268
                return FALSE;
269
            case EAP::INTEGER_FAST_GTC:
270
            case EAP::INTEGER_PEAP_MSCHAP2:
271
            case EAP::INTEGER_TTLS_GTC:
272
            case EAP::INTEGER_TTLS_MSCHAP2:
273
            case EAP::INTEGER_TTLS_PAP:
274
            case EAP::INTEGER_TLS:
275
            case EAP::INTEGER_SILVERBULLET:
276
                return TRUE;
277
            default:
278
                throw new Exception("Unable to determine if the EAP type requires a CA trust base for secure functioning or not!");
279
        }
280
    }
281
282
    /**
283
     * Does the EAP type require the specification of a server name to be secure?
284
     * EAP-pwd has one, but it is not really required.
285
     * @return boolean
286
     * @throws Exception
287
     */
288
    public function needsServerName()
289
    {
290
        switch ($this->intRep) {
291
            case EAP::INTEGER_FAST_GTC:
292
            case EAP::INTEGER_PEAP_MSCHAP2:
293
            case EAP::INTEGER_TTLS_GTC:
294
            case EAP::INTEGER_TTLS_MSCHAP2:
295
            case EAP::INTEGER_TTLS_PAP:
296
            case EAP::INTEGER_TLS:
297
            case EAP::INTEGER_SILVERBULLET:
298
                return TRUE;
299
            case EAP::INTEGER_EAP_PWD:
300
                return FALSE;
301
            default:
302
                throw new Exception("Unable to determine if the EAP type requires a server name trust base for secure functioning or not!");
303
        }
304
    }
305
306
    /**
307
     * Returns the Array representation of the EAP type.
308
     * 
309
     * @return array
310
     */
311
    public function getArrayRep()
312
    {
313
        return $this->arrayRep;
314
    }
315
316
    /**
317
     * Returns the int representation of the EAP type.
318
     * 
319
     * @return int
320
     */
321
    public function getIntegerRep()
322
    {
323
        return $this->intRep;
324
    }
325
326
    /**
327
     * This function takes the EAP method in array representation (OUTER/INNER) and returns it in a custom format for the
328
     * Linux installers (not numbers, but strings as values).
329
     * @param array $eap EAP method in array representation (OUTER/INNER)
330
     * @return array EAP method in array representation (OUTER as string/INNER as string)
331
     */
332
    public static function eapDisplayName($eap)
333
    {
334
        $eapDisplayName = [];
335
        $eapDisplayName[serialize(EAP::EAPTYPE_PEAP_MSCHAP2)] = ["OUTER" => 'PEAP', "INNER" => 'MSCHAPV2'];
336
        $eapDisplayName[serialize(EAP::EAPTYPE_TLS)] = ["OUTER" => 'TLS', "INNER" => ''];
337
        $eapDisplayName[serialize(EAP::EAPTYPE_TTLS_PAP)] = ["OUTER" => 'TTLS', "INNER" => 'PAP'];
338
        $eapDisplayName[serialize(EAP::EAPTYPE_TTLS_MSCHAP2)] = ["OUTER" => 'TTLS', "INNER" => 'MSCHAPV2'];
339
        $eapDisplayName[serialize(EAP::EAPTYPE_TTLS_GTC)] = ["OUTER" => 'TTLS', "INNER" => 'GTC'];
340
        $eapDisplayName[serialize(EAP::EAPTYPE_FAST_GTC)] = ["OUTER" => 'FAST', "INNER" => 'GTC'];
341
        $eapDisplayName[serialize(EAP::EAPTYPE_PWD)] = ["OUTER" => 'PWD', "INNER" => ''];
342
        $eapDisplayName[serialize(EAP::EAPTYPE_NONE)] = ["OUTER" => '', "INNER" => ''];
343
        $eapDisplayName[serialize(EAP::EAPTYPE_SILVERBULLET)] = ["OUTER" => 'TLS', "INNER" => 'SILVERBULLET'];
344
        $eapDisplayName[serialize(EAP::EAPTYPE_ANY)] = ["OUTER" => 'PEAP TTLS TLS', "INNER" => 'MSCHAPV2 PAP GTC'];
345
        return($eapDisplayName[serialize($eap)]);
346
    }
347
348
    /**
349
     * determines the inner authentication. Is it EAP, and which mechanism is used to convey actual auth data
350
     * @param array $eap the EAP type for which we want to get the inner auth
351
     * @return array
352
     */
353
    public static function innerAuth($eap)
354
    {
355
        $out = [];
356
        $out['METHOD'] = $eap["INNER"];
357
        $out['EAP'] = 0;
358
        // override if there is an inner EAP
359
        if ($eap["INNER"] > 0) { // there is an inner EAP method
360
            $out['EAP'] = 1;
361
        }
362
        return $out;
363
    }
364
365
    /**
366
     * This function enumerates all known EAP types and returns them as array
367
     * 
368
     * @return array of all EAP types the CAT knows about, as objects
369
     */
370
    public static function listKnownEAPTypes()
371
    {
372
        $retval = [];
373
374
        foreach (array_values(EAP::EAPTYPES_CONVERSION) as $oneArrayRep) {
375
            $retval[] = new EAP($oneArrayRep);
376
        }
377
        return $retval;
378
    }
379
380
    /**
381
     * returns a printable ("pretty-print") version of the EAP type
382
     * @return string
383
     */
384
    public function getPrintableRep()
385
    {
386
        Entity::intoThePotatoes();
387
        $nameMapping = [
388
            _("PEAP-MSCHAPv2") => \core\common\EAP::EAPTYPE_PEAP_MSCHAP2,
389
            _("TLS") => \core\common\EAP::EAPTYPE_TLS,
390
            _("TTLS-PAP") => \core\common\EAP::EAPTYPE_TTLS_PAP,
391
            _("TTLS-MSCHAPv2") => \core\common\EAP::EAPTYPE_TTLS_MSCHAP2,
392
            _("TTLS-GTC") => \core\common\EAP::EAPTYPE_TTLS_GTC,
393
            _("FAST-GTC") => \core\common\EAP::EAPTYPE_FAST_GTC,
394
            _("EAP-pwd") => \core\common\EAP::EAPTYPE_PWD,
395
            \core\ProfileSilverbullet::PRODUCTNAME => \core\common\EAP::EAPTYPE_SILVERBULLET,
396
        ];
397
        $find = array_keys($nameMapping, $this->arrayRep, TRUE);
398
        Entity::outOfThePotatoes();
399
        return $find[0];
400
    }
401
}