Passed
Push — master ( 17bffe...10bee5 )
by Stefan
06:13
created

EAP::isPasswordOptional()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 2
c 0
b 0
f 0
rs 10
cc 1
eloc 1
nc 1
nop 0
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 int
168
     * @throws Exception
169
     */
170 View Code Duplication
    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;
0 ignored issues
show
Bug Best Practice introduced by
The expression return TRUE returns the type true which is incompatible with the documented return type integer.
Loading history...
179
            case EAP::INTEGER_TLS:
180
            case EAP::INTEGER_SILVERBULLET:
181
                return FALSE;
0 ignored issues
show
Bug Best Practice introduced by
The expression return FALSE returns the type false which is incompatible with the documented return type integer.
Loading history...
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 int
199
     * @throws Exception
200
     */
201 View Code Duplication
    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;
0 ignored issues
show
Bug Best Practice introduced by
The expression return FALSE returns the type false which is incompatible with the documented return type integer.
Loading history...
210
            case EAP::INTEGER_TLS:
211
            case EAP::INTEGER_SILVERBULLET:
212
                return TRUE;
0 ignored issues
show
Bug Best Practice introduced by
The expression return TRUE returns the type true which is incompatible with the documented return type integer.
Loading history...
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
     */
221 View Code Duplication
    public function isClientCertOptional() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
222
        switch ($this->intRep) {
223
            case EAP::INTEGER_EAP_PWD:
224
            case EAP::INTEGER_TLS:
225
            case EAP::INTEGER_SILVERBULLET:
226
                return FALSE;
227
            case EAP::INTEGER_FAST_GTC:
228
            case EAP::INTEGER_PEAP_MSCHAPv2:
229
            case EAP::INTEGER_TTLS_GTC:
230
            case EAP::INTEGER_TTLS_MSCHAP2:
231
            case EAP::INTEGER_TTLS_PAP:
232
                return TRUE;
233
            default:
234
                throw new Exception("Unable to determine if the EAP type has optional client-certificates or not!");
235
        }
236
    }
237
238
    /**
239
     * Does the EAP type require the specification of trusted CAs to be secure?
240
     * @return bool
241
     * @throws Exception
242
     */
243 View Code Duplication
    public function needsServerCACert() {
244
        switch ($this->intRep) {
245
            case EAP::INTEGER_EAP_PWD:
246
                return FALSE;
247
            case EAP::INTEGER_FAST_GTC:
248
            case EAP::INTEGER_PEAP_MSCHAPv2:
249
            case EAP::INTEGER_TTLS_GTC:
250
            case EAP::INTEGER_TTLS_MSCHAP2:
251
            case EAP::INTEGER_TTLS_PAP:
252
            case EAP::INTEGER_TLS:
253
            case EAP::INTEGER_SILVERBULLET:
254
                return TRUE;
255
            default:
256
                throw new Exception("Unable to determine if the EAP type requires a CA trust base for secure functioning or not!");
257
        }
258
    }
259
260
    /**
261
     * Does the EAP type require the specification of a server name to be secure?
262
     * EAP-pwd has one, but it is not really required.
263
     * @return bool
264
     * @throws Exception
265
     */
266 View Code Duplication
    public function needsServerName() {
267
        switch ($this->intRep) {
268
            case EAP::INTEGER_FAST_GTC:
269
            case EAP::INTEGER_PEAP_MSCHAPv2:
270
            case EAP::INTEGER_TTLS_GTC:
271
            case EAP::INTEGER_TTLS_MSCHAP2:
272
            case EAP::INTEGER_TTLS_PAP:
273
            case EAP::INTEGER_TLS:
274
            case EAP::INTEGER_SILVERBULLET:
275
                return TRUE;
276
            case EAP::INTEGER_EAP_PWD:
277
                return FALSE;
278
            default:
279
                throw new Exception("Unable to determine if the EAP type requires a server name trust base for secure functioning or not!");
280
        }
281
    }
282
283
    /**
284
     * Returns the Array representation of the EAP type.
285
     * 
286
     * @return array
287
     */
288
    public function getArrayRep() {
289
        return $this->arrayRep;
290
    }
291
292
    /**
293
     * Returns the int representation of the EAP type.
294
     * 
295
     * @return int
296
     */
297
    public function getIntegerRep() {
298
        return $this->intRep;
299
    }
300
301
    /**
302
     * This function takes the EAP method in array representation (OUTER/INNER) and returns it in a custom format for the
303
     * Linux installers (not numbers, but strings as values).
304
     * @param array EAP method in array representation (OUTER/INNER)
305
     * @return array EAP method in array representation (OUTER as string/INNER as string)
306
     */
307
    public static function eapDisplayName($eap) {
308
        $eapDisplayName = [];
309
        $eapDisplayName[serialize(EAP::EAPTYPE_PEAP_MSCHAP2)] = ["OUTER" => 'PEAP', "INNER" => 'MSCHAPV2'];
310
        $eapDisplayName[serialize(EAP::EAPTYPE_TLS)] = ["OUTER" => 'TLS', "INNER" => ''];
311
        $eapDisplayName[serialize(EAP::EAPTYPE_TTLS_PAP)] = ["OUTER" => 'TTLS', "INNER" => 'PAP'];
312
        $eapDisplayName[serialize(EAP::EAPTYPE_TTLS_MSCHAP2)] = ["OUTER" => 'TTLS', "INNER" => 'MSCHAPV2'];
313
        $eapDisplayName[serialize(EAP::EAPTYPE_TTLS_GTC)] = ["OUTER" => 'TTLS', "INNER" => 'GTC'];
314
        $eapDisplayName[serialize(EAP::EAPTYPE_FAST_GTC)] = ["OUTER" => 'FAST', "INNER" => 'GTC'];
315
        $eapDisplayName[serialize(EAP::EAPTYPE_PWD)] = ["OUTER" => 'PWD', "INNER" => ''];
316
        $eapDisplayName[serialize(EAP::EAPTYPE_NONE)] = ["OUTER" => '', "INNER" => ''];
317
        $eapDisplayName[serialize(EAP::EAPTYPE_SILVERBULLET)] = ["OUTER" => 'TLS', "INNER" => 'SILVERBULLET'];
318
        $eapDisplayName[serialize(EAP::EAPTYPE_ANY)] = ["OUTER" => 'PEAP TTLS TLS', "INNER" => 'MSCHAPV2 PAP GTC'];
319
        return($eapDisplayName[serialize($eap)]);
320
    }
321
322
    /**
323
     * determines the inner authentication. Is it EAP, and which mechanism is used to convey actual auth data
324
     * @param array $eap
325
     * @return array
326
     */
327
    public static function innerAuth($eap) {
328
        $out = [];
329
        if ($eap["INNER"]) { // there is an inner EAP method
330
            $out['EAP'] = 1;
331
            $out['METHOD'] = $eap["INNER"];
332
            return $out;
333
        }
334
        // there is none
335
        $out['EAP'] = 0;
336
        switch ($eap) {
337
            case EAP::EAPTYPE_TTLS_PAP:
338
                $out['METHOD'] = EAP::NE_PAP;
339
                break;
340
            case EAP::EAPTYPE_TTLS_MSCHAP2:
341
                $out['METHOD'] = EAP::NE_MSCHAP2;
342
        }
343
        return $out;
344
    }
345
346
    /**
347
     * This function enumerates all known EAP types and returns them as array
348
     * 
349
     * @return array of all EAP types the CAT knows about, as objects
350
     */
351
    public static function listKnownEAPTypes() {
352
        $retval = [];
353
354
        foreach (array_values(EAP::EAPTYPES_CONVERSION) as $oneArrayRep) {
355
            $retval[] = new EAP($oneArrayRep);
356
        }
357
        return $retval;
358
    }
359
360
    /**
361
     * returns a printable ("pretty-print") version of the EAP type
362
     * @return string
363
     */
364
    public function getPrintableRep() {
365
        $nameMapping = [
366
            _("PEAP-MSCHAPv2") => \core\common\EAP::EAPTYPE_PEAP_MSCHAP2,
367
            _("TLS") => \core\common\EAP::EAPTYPE_TLS,
368
            _("TTLS-PAP") => \core\common\EAP::EAPTYPE_TTLS_PAP,
369
            _("TTLS-MSCHAPv2") => \core\common\EAP::EAPTYPE_TTLS_MSCHAP2,
370
            _("TTLS-GTC") => \core\common\EAP::EAPTYPE_TTLS_GTC,
371
            _("FAST-GTC") => \core\common\EAP::EAPTYPE_FAST_GTC,
372
            _("EAP-pwd") => \core\common\EAP::EAPTYPE_PWD,
373
            \core\ProfileSilverbullet::PRODUCTNAME => \core\common\EAP::EAPTYPE_SILVERBULLET,
374
        ];
375
        $find = array_keys($nameMapping, $this->arrayRep, TRUE);
376
        return $find[0];
377
    }
378
379
}
380