Passed
Push — master ( 5c87ed...e4bb53 )
by Stefan
04:05
created

EAP   D

Complexity

Total Complexity 61

Size/Duplication

Total Lines 343
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 61
dl 0
loc 343
rs 4.054
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 16 5
A isPasswordOptional() 0 2 1
A listKnownEAPTypes() 0 7 2
A getArrayRep() 0 2 1
A innerAuth() 0 17 4
A eapDisplayName() 0 13 1
A getIntegerRep() 0 2 1
A getPrintableRep() 0 13 1
B isClientCertOptional() 0 14 9
B isPasswordRequired() 0 14 9
B needsServerName() 0 14 9
B needsServerCACert() 0 14 9
B isClientCertRequired() 0 14 9

How to fix   Complexity   

Complex Class

Complex classes like EAP often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use EAP, and based on these observations, apply Extract Interface, too.

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