RADIUSTestsUI   F
last analyzed

Complexity

Total Complexity 110

Size/Duplication

Total Lines 548
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 110
eloc 369
dl 0
loc 548
rs 2
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 61 9
A setGlobalStaticResult() 0 4 2
A getTimeStamp() 0 3 1
B printDynamic() 0 32 7
F collectCAPath() 0 71 19
C setGlobalDynamicResult() 0 47 17
C printStatic() 0 54 12
D collectClients() 0 99 21
A isDynamic() 0 6 2
F printOverview() 0 96 20

How to fix   Complexity   

Complex Class

Complex classes like RADIUSTestsUI 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 RADIUSTestsUI, and based on these observations, apply Extract Interface, too.

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 code for testing presenting tests result
25
 *
26
 * @author Maja Gorecka-Wolniewicz <[email protected]>
27
 *
28
 * @package Developer
29
 * 
30
 */
31
32
namespace core\diag;
33
34
use \Exception;
0 ignored issues
show
Bug introduced by
The type \Exception 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...
35
36
class RADIUSTestsUI extends AbstractTest
37
{
38
39
    /**
40
     * This private variable contains the realm to be checked. Is filled in the
41
     * class constructor.
42
     * 
43
     * @var string
44
     */
45
    public $realm = NULL;
46
    public $outerUser = NULL;
47
48
    /**
49
     * result of the reachability tests
50
     * 
51
     * @var array
52
     */
53
    public $allReachabilityResults = [];
54
    
55
    private $hostMap = [];
56
    private $protocolsMap = [];
57
    private $globalLevelStatic = \core\common\Entity::L_OK;
58
    private $globalLevelDynamic = \core\common\Entity::L_OK;
59
    private $rfc7585suite = NULL;
60
    private $srv;
61
    private $naptr;
62
    private $naptrValid;
63
    private $hosts;
64
    private $testSuite;
65
    private $areFailed = FALSE;
66
    private $globalInfo = [];
67
    private $stateIcons = [];
68
    private $states;
69
    private $certFields;
70
    private $timestamp;
71
    const RADIUS_TEST_OPERATION_MODE_SHALLOW = 1;
72
    const RADIUS_TEST_OPERATION_MODE_THOROUGH = 2;
73
    
74
    
75
76
    /**
77
     * Constructor for the RADIUSTestsUI class. The single mandatory parameter is the
78
     * token indicating tests that were carried out and saved as JSON files.
79
     * 
80
     * @param string $token                  the token which points to a directory
81
     * @throws Exception
82
     */
83
    public function __construct($token)
84
    {
85
        parent::__construct();
86
        $this->globalInfo = [
87
            \core\common\Entity::L_OK => _("All tests passed."),
88
            \core\common\Entity::L_WARN => _("There were some warnings."),
89
            \core\common\Entity::L_ERROR => _("There were some errors."),
90
            \core\common\Entity::L_REMARK => _("There were some remarks.")
91
        ]; 
92
        $this->stateIcons = [
93
            \core\common\Entity::L_OK => '../resources/images/icons/Tabler/square-rounded-check-filled-green.svg',
94
            \core\common\Entity::L_WARN => '../resources/images/icons/Tabler/alert-square-rounded-filled-yellow.svg',
95
            \core\common\Entity::L_ERROR => '../resources/images/icons/Tabler/square-rounded-x-filled-red.svg',
96
            \core\common\Entity::L_REMARK => '../resources/images/icons/Tabler/info-square-rounded-filled-blue.svg'
97
        ];
98
        $this->states = [
99
            'PASS' => _("PASS"),
100
            'FAIL' => _("FAIL")
101
        ];
102
        $this->certFields = [
103
            'subject' => _("Subject:"),
104
            'issuer' => _("Issuer:"),
105
            'validFrom' =>  _("Valid from:"),
106
            'validTo' => _("Valid to:"),
107
            'serialNumber' => _("Serial number:"),
108
            'sha1' => _("SHA1 fingerprint:"),
109
            'public_key_length' => _("Public key length:"),
110
            'title' => _("Server certificate"),
111
            'policies' => _("Policies:"),
112
            'crldistributionpoints' =>  _("crlDistributionPoint:"),
113
            'authorityinfoaccess' => _("authorityInfoAccess:"),
114
            'subjectaltname' => _("SubjectAltName:"),
115
        ];
116
        $jsondir = dirname(dirname(dirname(__FILE__)))."/var/json_cache";
117
        if ($token && is_dir($jsondir.'/'.$token)) {
118
            foreach (['realm', 'udp', 'clients', 'capath'] as $test_type) {
119
                foreach (glob("$jsondir/$token/$test_type*") as $filename) {
120
                    $this->loggerInstance->debug(4, "\nIS_DIR $filename\n");
121
                    if (!array_key_exists($test_type, $this->allReachabilityResults)) {
122
                        $this->allReachabilityResults[$test_type] = array();
123
                    }
124
                    $this->allReachabilityResults[$test_type][] = json_decode(file_get_contents($filename));
125
                }   
126
            }
127
            if ($this->allReachabilityResults['realm'][0]->realm) {
128
                $this->realm = $this->allReachabilityResults['realm'][0]->realm;
129
                $this->outerUser = $this->allReachabilityResults['realm'][0]->outeruser;
130
                foreach ($this->allReachabilityResults['realm'][0]->totest as $totest) {
131
                    $this->hostMap[$totest->host] = $totest->bracketaddr;
132
                    if (property_exists($totest, 'protocols')) {
133
                        $this->protocolsMap[$totest->host] = $totest->protocols;
134
                    }
135
                }
136
                $this->rfc7585suite = unserialize(base64_decode($this->allReachabilityResults['realm'][0]->rfc7585suite));
137
                $this->srv = $this->allReachabilityResults['realm'][0]->srv;
138
                $this->naptr = $this->allReachabilityResults['realm'][0]->naptr;
139
                $this->naptrValid = $this->allReachabilityResults['realm'][0]->naptr_valid;
140
                $this->hosts = $this->allReachabilityResults['realm'][0]->hosts;
141
                $this->testSuite = unserialize(base64_decode($this->allReachabilityResults['realm'][0]->testsuite));
142
            }
143
            $this->timestamp = $this->allReachabilityResults['realm'][0]->datetime;
144
        }
145
    }
146
    
147
    public function getTimeStamp()
148
    { 
149
        return $this->timestamp;
150
    }
151
    /**
152
     * sets the global status for static tests
153
     */
154
    public function setGlobalStaticResult()
155
    { 
156
        foreach ($this->allReachabilityResults['udp'] as $udp) {
157
            $this->globalLevelStatic = max($this->globalLevelStatic, $udp->result[0]->level);
158
        }
159
    }
160
    
161
    public function setGlobalDynamicResult()
162
    {
163
        if (isset($this->allReachabilityResults['capath'])) {
164
            foreach ($this->allReachabilityResults['capath'] as $capath) {
165
                $this->globalLevelDynamic = max($this->globalLevelDynamic, $capath->level);
166
            }
167
        }
168
        if (isset($this->allReachabilityResults['clients'])) {
169
            foreach ($this->allReachabilityResults['clients'] as $clients) {
170
                $srefused = FALSE;
171
                $level = \core\common\Entity::L_OK;
172
                $maxlevel = $level;
173
                foreach ($clients->ca as $ca) {
174
                    foreach ($ca->certificate as $certificate) {
175
                        if ($certificate->returncode == \core\diag\RADIUSTests::RETVAL_CONNECTION_REFUSED) {
176
                            $srefused = $this->areFailed = TRUE;
177
                        }
178
                    }
179
                    if (!$srefused) {
180
                        foreach ($clients->ca as $cca) {
181
                            foreach ($cca->certificate as $certificate) {
182
                                $level = $certificate->returncode;
183
                                if ($level < 0) {
184
                                    $level = \core\common\Entity::L_ERROR;
185
                                    $this->areFailed = TRUE;
186
                                }
187
                                if ($certificate->expected != 'PASS') {
188
                                    if ($certificate->connected == 1) {
189
                                        $level = \core\common\Entity::L_WARN;
190
                                    } else {
191
                                        
192
                                        if ($certificate->status == 'EXPIRED' && property_exists($certificate, 'reason')) {
193
                                            //print '<pre>'; print_r($certificate); print '</pre>';
194
                                            $level = \core\common\Entity::L_WARN;
195
                                        } else {
196
                                            $level = \core\common\Entity::L_OK;
197
                                        }
198
                                    }
199
                                }
200
                                if ($level > $maxlevel) {
201
                                    $maxlevel = $level;
202
                                }
203
                            }
204
                        }
205
                    } 
206
                }
207
                $this->globalLevelDynamic = max($this->globalLevelDynamic, $maxlevel);
208
            }
209
        }
210
    }           
211
212
    public function isDynamic()
213
    {
214
        if ($this->naptr > 0) {
215
            return TRUE;
216
        }
217
        return FALSE;
218
    }
219
    /**
220
     * prints tabs-1
221
     * 
222
     * 
223
     */
224
    public function printOverview()
225
    {
226
        $out = [];
227
        $out[] = "<fieldset class='option_container'>
228
        <legend>
229
        <strong>"._("Overview").'</strong> 
230
        </legend>';
231
        $out[] = "<strong>"._("DNS checks")."</strong><div>";
232
        if ($this->naptr != \core\diag\RADIUSTests::RETVAL_NOTCONFIGURED) {
233
            $out[] = "<table>";
234
            $out[] = "<tr><td>"._("Checking NAPTR existence:")."</td><td>";
235
            switch ($this->naptr) {
236
                case \core\diag\RFC7585Tests::RETVAL_NONAPTR:
237
                    $out[] = _("This realm has no NAPTR records.");
238
                    break;
239
                case \core\diag\RFC7585Tests::RETVAL_ONLYUNRELATEDNAPTR:
240
                    $out[] = _("This realm has NAPTR records, but none are related to this roaming consortium.");
241
                    break;
242
                default: // if none of the possible negative retvals, then we have matching NAPTRs
243
                    $out[] = sprintf(_("This realm has %d NAPTR records relating to this roaming consortium."), $this->naptr);
244
            }
245
            $out[] = "</td></tr>";
246
          
247
            if ($this->naptr > 0) {
248
                $out[] = "<tr><td>"._("Checking NAPTR compliance (flag = S and regex = {empty}):")."</td><td>";
249
                switch ($this->naptrValid) {
250
                    case \core\diag\RADIUSTests::RETVAL_OK:
251
                        $out[] = "No issues found.";
252
                        break;
253
                    case \core\diag\RADIUSTests::RETVAL_INVALID:
254
                        $out[] = _("At least one NAPTR with invalid content found!");
255
                        break;
256
                }
257
                $out[] = "</td></tr>";
258
            }
259
            // SRV resolution
260
            if ($this->naptr > 0 && $this->naptrValid == \core\diag\RADIUSTests::RETVAL_OK) {
261
                $out[] = "<tr><td>"._("Checking SRVs:")."</td><td>";
262
                switch ($this->srv) {
263
                    case \core\diag\RADIUSTests::RETVAL_SKIPPED:
264
                        $out[] = _("This check was skipped.");
265
                        break;
266
                    case \core\diag\RADIUSTests::RETVAL_INVALID:
267
                        $out[] = _("At least one NAPTR with invalid content found!");
268
                        break;
269
                    default: // print number of successfully retrieved SRV targets
270
                        $out[] = sprintf(_("%d host names discovered."), $this->srv);
271
                }
272
                $out[] = "</td></tr>";
273
            }
274
            // IP addresses for the hosts
275
            if ($this->naptr > 0 && $this->naptrValid == \core\diag\RADIUSTests::RETVAL_OK && $this->srv > 0) {
276
                $out[] = "<tr><td>"._("Checking IP address resolution:")."</td><td>";
277
                switch ($this->srv) {
278
                    case \core\diag\RADIUSTests::RETVAL_SKIPPED:
279
                        $out[] = _("This check was skipped.");
280
                        break;
281
                    case \core\diag\RADIUSTests::RETVAL_INVALID:
282
                        $out[] = _("At least one hostname could not be resolved!");
283
                        break;
284
                    default: // print number of successfully retrieved SRV targets
285
                        $out[] = sprintf(_("%d IP addresses resolved."), $this->hosts);
286
                }
287
                $out[] = "</td></tr>";
288
            }
289
290
            $out[] = "</table><br/>";
291
            $out[] = sprintf(_("Realm is <strong>%s</strong> "), _(($this->naptr > 0 ? "DYNAMIC" : "STATIC")));
292
            if (count($this->testSuite->listerrors()) == 0) {
293
                $out[] = _("with no DNS errors encountered. Congratulations!");
294
            } else {
295
                $out[] = _("but there were DNS errors! Check them!")." "._("You should re-run the tests after fixing the errors; more errors might be uncovered at that point. The exact error causes are listed below.");
296
                $out[] = "<div class='notacceptable'><table>";
297
                foreach ($this->testSuite->listerrors() as $details) {
298
                    $out[] = "<tr><td>".$details['TYPE']."</td><td>".$details['TARGET']."</td></tr>";
299
                }
300
                $out[] = "</table></div>";
301
            }
302
            $out[] = '</div>';
303
        } else {
304
            $out[] = "<tr><td>"._("Dynamic discovery test is not configured")."</td><td>";
305
        }
306
        $out[] = "<hr><strong>"._("Static connectivity tests")."</strong>
307
         <table><tr>
308
         <td class='icon_td'>";
309
        $out[] = "<img src='".$this->stateIcons[$this->globalLevelStatic]."' id='main_static_ico' class='icon'></td><td id='main_static_result'>".
310
                            $this->globalInfo[$this->globalLevelStatic].' '. _("See the appropriate tab for details.").'</td>
311
         </tr></table>';
312
        if ($this->naptr > 0) {
313
            $out[] = "<hr><strong>"._("Dynamic connectivity tests")."</strong>
314
            <table><tr>
315
            <td class='icon_td'><img src='".$this->stateIcons[$this->globalLevelDynamic]."' id='main_dynamic_ico' class='icon'></td><td id='main_dynamic_result'>".
316
            $this->globalInfo[$this->globalLevelDynamic].' '._("See the appropriate tab for details.").'</td></tr></table>';
317
        }
318
        $out[] = '</fieldset>';
319
        return join('', $out);
320
    }
321
    
322
    public function printStatic()
323
    {
324
        $out = [];
325
        $out[] = '<fieldset class="option_container" id="static_tests">
326
                  <legend><strong>';
327
        $out[] = _("STATIC connectivity tests");
328
        $out[] = '</strong> </legend>';
329
        $out[] = _("This check sends a request for the realm through various entry points of the roaming consortium infrastructure. The request will contain the 'Operator-Name' attribute, and will be larger than 1500 Bytes to catch two common configuration problems.<br/>Since we don't have actual credentials for the realm, we can't authenticate successfully - so the expected outcome is to get an Access-Reject after having gone through an EAP conversation.");
330
        $out[] = '<p>';
331
        foreach ($this->allReachabilityResults['udp'] as $udp) {
332
            $hostindex = $udp->hostindex;
333
            $result = $udp->result[0];
334
            $out[] = '<hr>';
335
            $out[] = sprintf(_("Testing from: <strong>%s"), \config\Diagnostics::RADIUSTESTS['UDP-hosts'][$hostindex]['display_name']).'</strong>';
336
            $out[] = '<ul style="list-style-type: none;"><li>';
337
            $out[] = "<table id='results$hostindex'  style='width:100%' class='udp_results'>
338
<tr>
339
<td class='icon_td'><img src='".$this->stateIcons[$result->level]."' id='src".$hostindex."_img'></td>
340
<td id='src$hostindex' colspan=2>
341
";
342
            $out[] = '<strong>'.($result->server ? $result->server : _("Connected to undetermined server")).'</strong><br/>'.sprintf (_("elapsed time: %sms."), $result->time_millisec).'<div>'.$result->message.'</div>';
343
                    
344
            if ($result->level > \core\common\Entity::L_OK && property_exists($result, 'cert_oddities')) {
345
                foreach ($result->cert_oddities as $oddities) {
346
                    $out[] = '<tr class="results_tr"><td>&nbsp;</td><td class="icon_td"><img src="'.$this->stateIcons[$oddities->level].'"></td><td>'.$oddities->message.'</td></tr>';
347
                }
348
            }
349
            $more = '';
350
            if ($result->server_cert) {
351
                $more .= '<div class="more">';
352
                $certdesc = '<br>'.$this->certFields['title'].'<ul>';
353
                foreach ($result->server_cert as $sckey => $sc) {
354
                    if (array_key_exists($sckey, $this->certFields)) {
355
                        $certdesc .= '<li>'.$this->certFields[$sckey].' '.$sc;
356
                    }
357
                }
358
                if ($result->server_cert->extensions) {
359
                    $certdesc .= '<li>' . _('Extensions') . '<ul>';
360
                    foreach ($result->server_cert->extensions as $ekey => $eval) {
361
                        $certdesc .= '<li>' . $ekey . ': ' . $eval;
362
                    }
363
                    $certdesc .= '</ul>';
364
                }
365
                $certdesc .= '</ul>';
366
                $more .= '<span class="morecontent"><span>'.$certdesc.
367
                        '</span><a href="" class="morelink">'._("show server certificate details").'&raquo;</a></span></div>';
368
            }     
369
            if ($more != '' ) {
370
                $out[] = '<tr><td>&nbsp;</td><td colspan="2">'.$more.'</td></tr>';
371
            }
372
            $out[] = "</table></ul>";
373
        }
374
        $out[] = '</fieldset>';
375
        return join('', $out);            
376
    }
377
    
378
    private function collectCAPath()
379
    {
380
        $capathtest = [];
381
        $capathtest[] = '<p><strong>'._("Checking server handshake...")."</strong><p>";
382
        foreach ($this->allReachabilityResults['capath'] as $capath) {
383
            $hostindex = $capath->hostindex;
384
            $level = $capath->level;
385
            if ($capath->level == \core\common\Entity::L_OK && $capath->result == \core\diag\RADIUSTests::RETVAL_INVALID) {
386
                $level = \core\common\Entity::L_WARN;
387
            }
388
            $capathtest[] = '<p><strong>'.$this->hostMap[$capath->IP].'</strong> ('.$capath->name.') ';
389
            $prots = [];
390
            if (isset($this->protocolsMap[$capath->IP]) && $this->protocolsMap[$capath->IP] != '') {
391
                $prots = explode(';', $this->protocolsMap[$capath->IP]);
392
                if (!empty($prots)) {
393
                    $capathtest[] = ' ' . _("supported TLS protocols: ");
394
                    $capathtest[] = implode(', ', $prots);
395
                    if (!in_array("TLS1.3", $prots)) {
396
                        $capathtest[] =  ' ' . '<font color="red">' . _("not supported: ") . 'TLS1.3</font>';
397
                    }
398
                }
399
            }
400
            $capathtest[] = '<ul style="list-style-type: none;" class="caresult"><li>';
401
            $capathtest[] = "<table id='caresults$hostindex'  style='width:100%'>
402
<tr>
403
<td class='icon_td'><img src='";
404
            $capathtest[] = $this->stateIcons[$level]."' id='srcca".$hostindex."_img'></td>
405
<td id='srcca$hostindex'>";
406
            $more = '';
407
            if ($capath->certdata && $capath->certdata->subject != '') {
408
                $more .= '<div class="more">';
409
                $certdesc = '<br>'.$this->certFields['title'].'<ul>';
410
                if ($capath->certdata->subject) {
411
                    $certdesc .= '<li>'.$this->certFields['subject'].' '.$capath->certdata->subject;
412
                }
413
                if ($capath->certdata->issuer) {
414
                    $certdesc .= '<li>'.$this->certFields['issuer'].' '.$capath->certdata->issuer;
415
                }
416
                if ($capath->certdata->validTo) {
417
                    $certdesc .= '<li>'.$this->certFields['validTo'].' '.
418
                            date_create_from_format('ymdGis', 
419
                                    substr($capath->certdata->validTo, 0, -1))->format('Y-m-d H:i:s'). ' UTC';
420
                }
421
                if ($capath->certdata->extensions) {
422
                    if ($capath->certdata->extensions->subjectaltname) {                     
423
                        $certdesc .= '<li>'.$this->certFields['subjectaltname'].' '.$capath->certdata->extensions->subjectaltname;
424
                    }
425
                }
426
                if ($capath->certdata->extensions->policies) {
427
                    $certdesc .= '<li>'.$this->certFields['policies'].' '.$capath->certdata->extensions->policies;
428
                }
429
                if ($capath->certdata->extensions->crldistributionpoints) {
430
                    $certdesc .= '<li>'.$this->certFields['crldistributionpoints'].' '.$capath->certdata->extensions->crldistributionpoints;
431
                }
432
                if ($capath->certdata->extensions->authorityinfoaccess) {
433
                    $certdesc .= '<li>'.$this->certFields['authorityinfoaccess'].' '.$capath->certdata->extensions->authorityinfoaccess;
434
                }
435
                            
436
                $certdesc .= '</ul>';
437
                $more .= '<span class="morecontent"><span>'.$certdesc.$protocoldesc.
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $protocoldesc seems to be never defined.
Loading history...
438
                        '</span>&nbsp;&nbsp;<a href="" class="morelink">'._("more").'&raquo;</a></span></td></tr>';
439
            } else {
440
                $certdesc = '<br>';
441
            }
442
            $capathtest[] = '<div>'.($capath->message!='' ? $capath->message : _('Test failed')).'</div>'.$more;
443
            $capathtest[] = '</td>
444
</tr>
445
</table>';
446
            $capathtest[] = '</li></ul>';
447
        }
448
        return $capathtest;
449
    }
450
451
    private function collectClients()
452
    {
453
        $clientstest = [];
454
        foreach ($this->allReachabilityResults['clients'] as $clients) {
455
            if ($clients->result == RADIUSTests::RETVAL_SKIPPED) {
456
                continue;
457
            }
458
            $hostindex = $clients->hostindex; 
459
            $clientstest[] = '<p><strong>'.$this->hostMap[$clients->IP].'</strong></p>';
460
            $clientstest[] = "<span id='clientresults$hostindex'>";
461
            $clientstest[] = '<p></p>';
462
            if ($this->globalLevelDynamic != \core\common\Entity::L_ERROR) {
463
                if (property_exists($clients, 'ca')) {
464
                    $clientstest[] = '<ol>';
465
                    foreach ($clients->ca as $ca) {                     
466
                        $srefused = 0;
467
                        $cliinfo = '';
468
                        $cliinfo .= '<li>'._('Client certificate').' <b>'.$ca->clientcertinfo->from.
469
                                    '</b>'.', '.$ca->clientcertinfo->message .
470
                                    '<br> (CA: '.$ca->clientcertinfo->issuer.')<ul>';
471
                        foreach ($ca->certificate as $certificate) {
472
                            if ($certificate->returncode == \core\diag\RADIUSTests::RETVAL_CONNECTION_REFUSED) {
473
                                $srefused = 1;
474
                            }
475
                        }
476
                        if ($srefused == 0) {
477
                            foreach ($ca->certificate as $certificate) {                           
478
                                $cliinfo .= '<li><i>'.$certificate->message. 
479
                                            ', '._("expected result: ").$this->states[$certificate->expected].'</i>';
480
                                $cliinfo .= '<ul style="list-style-type: none;">';
481
                                if (property_exists($certificate, 'finalerror') && $certificate->finalerror == 2) {
482
                                        $cliinfo .= '<li>'._('this test was skipped - no appropriate client certificate').'</li></ul>';
483
                                        continue;
484
                                }
485
                                $level = $certificate->returncode;
486
                                if ($level < 0) {
487
                                    $level = \core\common\Entity::L_ERROR;
488
                                }
489
                                $add = '';
490
                                if ($certificate->expected == 'PASS') {
491
                                    if ($certificate->connected == 1) {
492
                                        $state = _("Server accepted this client certificate");
493
                                    } else {
494
                                        if (property_exists($certificate, 'reason') && $certificate->reason == \core\diag\RADIUSTests::CERTPROB_UNKNOWN_CA) {
495
                                            $add = '<br>'._('You should update your list of accredited CAs').
496
                                                            ' <a href=\"'.\config\Diagnostics::RADIUSTESTS['accreditedCAsURL'].'\">'.
497
                                                            _('Get it from here.').'</a>';
498
                                        }
499
                                        $state = _('Server did not accept this client certificate - reason').': '.
500
                                                    $certificate->resultcomment;
501
                                    }
502
                                } else {
503
                                    if ($certificate->connected == 1) {
504
                                        $level = \core\common\Entity::L_WARN;
505
                                        $state = _('Server accepted this client certificate, but should not have');
506
                                    } else {
507
                                        $level = \core\common\Entity::L_OK;
508
                                        $state = _('Server did not accept this client certificate').': '.$certificate->resultcomment;
509
                                    }
510
                                }
511
                                $cliinfo .= '<li><table><tbody><tr><td class="icon_td"><img class="icon" src="'.$this->stateIcons[$level].'" style="width: 24px;"></td><td>'.$state;
512
                                $cliinfo .= ' ('.sprintf(_('elapsed time: %sms.'), $certificate->time_millisec).'&nbsp;) '.$add.'</td></tr>';
513
                                $cliinfo .= '</tbody></table></ul></li>';
514
                                if (property_exists($certificate, 'finalerror')) {
515
                                    if ($certificate->finalerror == 1) {
516
                                        $cliinfo .= '<li>'._('Rest of tests for this CA skipped').'</li>';
517
                                    }
518
                                }
519
                            }
520
                            $cliinfo .= '</ul>';
521
                        }
522
                                    
523
                        if ($srefused > 0) {
524
                            $cliinfo = _('Connection refused');
525
                            $clientstest[] = "<table><tr><td class='icon_td' id='srcclient".$hostindex."_img'><img src='".$this->stateIcons[\core\common\Entity::L_ERROR]."'></td>".
526
                                        "<td id='srcclient$hostindex'><p>$cliinfo</p></td></tr></table>";
527
                        } else {
528
                            $clientstest[] = "<p>$cliinfo</p>";
529
                        }
530
                    }
531
                    
532
                } else {
533
                    $cliinfo = _('Test failed');
534
                    $clientstest[] = "<table><tr><td class='icon_td' id='srcclient".$hostindex."_img'><img src='".
535
                                    $this->stateIcons[\core\common\Entity::L_WARN]."'></td>" .
536
                                    "<td id='srcclient$hostindex'>$cliinfo</td></tr></table>";
537
                }
538
            } else {
539
                $clientstest[] = '<ul style="list-style-type: none;" class="clientsresult"><li>';
540
                $clientstest[] = "<table id='clientsresults$hostindex'  style='width:100%'>
541
<tr>
542
<td class='icon_td'><img src='";
543
                $clientstest[] = $this->stateIcons[\core\common\Entity::L_ERROR]."' id='srcclients".$hostindex."_img'></td>
544
<td id='srcclient$hostindex'>";
545
                $clientstest[] = _("These tests were skipped because of previous errors.").'</td></tr></table></ul>';
546
            }
547
            $clientstest[] = '</ol><p></p>';
548
        }
549
        return $clientstest;
550
    }
551
    
552
    public function printDynamic()
553
    {
554
        $out = [];
555
        $out[] = "<div id='dynamic_tests'><fieldset class='option_container'>
556
            <legend><strong>"._("DYNAMIC connectivity tests")."</strong></legend>";
557
        
558
        if (count($this->rfc7585suite->NAPTR_hostname_records) > 0) {    
559
            $capathtest = $this->collectCAPath();
560
            $clientstest = $this->collectClients();
561
            $out[] = '<div style="align:right;">';            
562
            $out[] = '<div style="align:right; display: ';
563
            if ($this->globalLevelDynamic == \core\common\Entity::L_OK && !$this->areFailed) {
564
                $out[] = 'none';
565
            }
566
            $out[] = ';" id="dynamic_result_fail"><b>'._("Some errors were found during the tests, see below").'</b></div>';
567
            $out[] = '<div style="align:right; display: ';
568
            if ($this->globalLevelDynamic != \core\common\Entity::L_OK || $this->areFailed) {
569
                $out[] = 'none';
570
            }
571
            $out[] = '" id="dynamic_result_pass"><b>'.
572
                                _("All tests passed, congratulations!").'</b></div>'.
573
                                '<div style="align:left;"><a href="" class="moreall"><i>'._('Show detailed information for all tests').'&raquo;</i></a></div>';
574
            $out[] = join('', $capathtest);
575
            if (!empty($clientstest)) {
576
                $out[] = '<span id="clientstest" style="display: ;"><p><hr><b>'._('Checking if certificates from CAs are accepted...').'</b><p>'._('A few client certificates will be tested to check if servers are resistant to some certificate problems.').'<p>';
577
                $out[] = join('', $clientstest);
578
                $out[] = '</span>';
579
            }
580
            $out[] = '</div>';
581
        }
582
        $out[] = "</fieldset></div></div>";
583
        return join('', $out);
584
    }
585
    
586
}
587