| Total Complexity | 90 |
| Total Lines | 751 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
Complex classes like DeviceConfig 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 DeviceConfig, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 57 | abstract class DeviceConfig extends \core\common\Entity { |
||
| 58 | |||
| 59 | /** |
||
| 60 | * stores the path to the temporary working directory for a module instance |
||
| 61 | * @var string $FPATH |
||
| 62 | */ |
||
| 63 | public $FPATH; |
||
| 64 | |||
| 65 | /** |
||
| 66 | * array of specialities - will be displayed on the admin download as "footnote" |
||
| 67 | * @var array specialities |
||
| 68 | */ |
||
| 69 | public $specialities; |
||
| 70 | |||
| 71 | /** |
||
| 72 | * list of supported EAP methods |
||
| 73 | * @var array EAP methods |
||
| 74 | */ |
||
| 75 | public $supportedEapMethods; |
||
| 76 | |||
| 77 | /** |
||
| 78 | * sets the supported EAP methods for a device |
||
| 79 | * |
||
| 80 | * @param array $eapArray the list of EAP methods the device supports |
||
| 81 | * @return void |
||
| 82 | */ |
||
| 83 | protected function setSupportedEapMethods($eapArray) { |
||
| 87 | } |
||
| 88 | |||
| 89 | /** |
||
| 90 | * device module constructor should be defined by each module. |
||
| 91 | * The one important thing to do is to call setSupportedEapMethods with an |
||
| 92 | * array of EAP methods the device supports |
||
| 93 | */ |
||
| 94 | public function __construct() { |
||
| 95 | parent::__construct(); |
||
| 96 | } |
||
| 97 | |||
| 98 | /** |
||
| 99 | * Set up working environment for a device module |
||
| 100 | * |
||
| 101 | * Sets up the device module environment taking into account the actual profile |
||
| 102 | * selected by the user in the GUI. The selected profile is passed as the |
||
| 103 | * Profile $profile argumant. |
||
| 104 | * |
||
| 105 | * This method needs to be called after the device instance has been created (the GUI class does that) |
||
| 106 | * |
||
| 107 | * setup performs the following tasks: |
||
| 108 | * - collect profile attributes and pass them as the attributes property; |
||
| 109 | * - create the temporary working directory |
||
| 110 | * - process CA certificates and store them as 'internal:CAs' attribute |
||
| 111 | * - process and save optional info files and store references to them in |
||
| 112 | * 'internal:info_file' attribute |
||
| 113 | * @param AbstractProfile $profile the profile object which will be passed by the caller |
||
| 114 | * @param string $token the invitation token for silverbullet requests |
||
| 115 | * @param string $importPassword the PIN for the installer for silverbullet requests |
||
| 116 | * @return void |
||
| 117 | * @final not to be redefined |
||
| 118 | */ |
||
| 119 | final public function setup(AbstractProfile $profile, $token = NULL, $importPassword = NULL) { |
||
| 120 | $this->loggerInstance->debug(4, "module setup start\n"); |
||
| 121 | common\Entity::intoThePotatoes(); |
||
| 122 | $purpose = 'installer'; |
||
| 123 | $eaps = $profile->getEapMethodsinOrderOfPreference(1); |
||
| 124 | $this->calculatePreferredEapType($eaps); |
||
| 125 | if (count($this->selectedEap) == 0) { |
||
| 126 | throw new Exception("No EAP type available."); |
||
| 127 | } |
||
| 128 | $this->attributes = $this->getProfileAttributes($profile); |
||
| 129 | $this->deviceUUID = common\Entity::uuid('', 'CAT' . $profile->institution . "-" . $profile->identifier . "-" . $this->device_id); |
||
| 130 | |||
| 131 | |||
| 132 | // if we are instantiating a Silverbullet profile AND have been given |
||
| 133 | // a token, attempt to create the client certificate NOW |
||
| 134 | // then, this is the only instance of the device ever which knows the |
||
| 135 | // cert and private key. It's not saved anywhere, so it's gone forever |
||
| 136 | // after code execution! |
||
| 137 | |||
| 138 | $this->loggerInstance->debug(5, "DeviceConfig->setup() - preliminaries done.\n"); |
||
| 139 | if ($profile instanceof ProfileSilverbullet && $token !== NULL && $importPassword !== NULL) { |
||
| 140 | $this->clientCert = SilverbulletCertificate::issueCertificate($token, $importPassword, $this->options['clientcert']); |
||
| 141 | // we need to drag this along; ChromeOS needs it outside the P12 container to encrypt the entire *config* with it. |
||
| 142 | // Because encrypted private keys are not supported as per spec! |
||
| 143 | $purpose = 'silverbullet'; |
||
| 144 | // let's keep a record for which device type this token was consumed |
||
| 145 | $dbInstance = DBConnection::handle("INST"); |
||
| 146 | $certId = $this->clientCert['certObject']->dbId; |
||
| 147 | $dbInstance->exec("UPDATE `silverbullet_certificate` SET `device` = ? WHERE `id` = ?", "si", $this->device_id, $certId); |
||
| 148 | } |
||
| 149 | $this->loggerInstance->debug(5, "DeviceConfig->setup() - silverbullet checks done.\n"); |
||
| 150 | // create temporary directory, its full path will be saved in $this->FPATH; |
||
| 151 | $tempDir = \core\common\Entity::createTemporaryDirectory($purpose); |
||
| 152 | $this->FPATH = $tempDir['dir']; |
||
| 153 | mkdir($tempDir['dir'] . '/tmp'); |
||
| 154 | chdir($tempDir['dir'] . '/tmp'); |
||
| 155 | $caList = []; |
||
| 156 | $x509 = new \core\common\X509(); |
||
| 157 | if (isset($this->attributes['eap:ca_file'])) { |
||
| 158 | foreach ($this->attributes['eap:ca_file'] as $ca) { |
||
| 159 | $processedCert = $x509->processCertificate($ca); |
||
| 160 | if (is_array($processedCert)) { |
||
| 161 | // add a UUID for convenience (some devices refer to their CAs by a UUID value) |
||
| 162 | $processedCert['uuid'] = common\Entity::uuid("", $processedCert['pem']); |
||
| 163 | $caList[] = $processedCert; |
||
| 164 | } |
||
| 165 | } |
||
| 166 | $this->attributes['internal:CAs'][0] = $caList; |
||
| 167 | } |
||
| 168 | |||
| 169 | if (isset($this->attributes['support:info_file'])) { |
||
| 170 | $this->attributes['internal:info_file'][0] = $this->saveInfoFile($this->attributes['support:info_file'][0]); |
||
| 171 | } |
||
| 172 | if (isset($this->attributes['general:logo_file'])) { |
||
| 173 | $this->loggerInstance->debug(5, "saving IDP logo\n"); |
||
| 174 | $this->attributes['internal:logo_file'] = $this->saveLogoFile($this->attributes['general:logo_file'],'idp'); |
||
| 175 | } |
||
| 176 | if (isset($this->attributes['fed:logo_file'])) { |
||
| 177 | $this->loggerInstance->debug(5, "saving FED logo\n"); |
||
| 178 | $this->attributes['fed:logo_file'] = $this->saveLogoFile($this->attributes['fed:logo_file'], 'fed'); |
||
| 179 | } |
||
| 180 | $this->attributes['internal:SSID'] = $this->getSSIDs()['add']; |
||
| 181 | |||
| 182 | $this->attributes['internal:remove_SSID'] = $this->getSSIDs()['del']; |
||
| 183 | |||
| 184 | $this->attributes['internal:consortia'] = $this->getConsortia(); |
||
| 185 | |||
| 186 | $this->support_email_substitute = sprintf(_("your local %s support"), CONFIG_CONFASSISTANT['CONSORTIUM']['display_name']); |
||
| 187 | $this->support_url_substitute = sprintf(_("your local %s support page"), CONFIG_CONFASSISTANT['CONSORTIUM']['display_name']); |
||
| 188 | |||
| 189 | if ($this->signer && $this->options['sign']) { |
||
| 190 | $this->sign = ROOT . '/signer/' . $this->signer; |
||
| 191 | } |
||
| 192 | $this->installerBasename = $this->getInstallerBasename(); |
||
| 193 | common\Entity::outOfThePotatoes(); |
||
| 194 | } |
||
| 195 | |||
| 196 | /** |
||
| 197 | * Selects the preferred eap method based on profile EAP configuration and device EAP capabilities |
||
| 198 | * |
||
| 199 | * @param array $eapArrayofObjects an array of eap methods supported by a given device |
||
| 200 | * @return void |
||
| 201 | */ |
||
| 202 | public function calculatePreferredEapType($eapArrayofObjects) { |
||
| 203 | $this->selectedEap = []; |
||
| 204 | foreach ($eapArrayofObjects as $eap) { |
||
| 205 | if (in_array($eap->getArrayRep(), $this->supportedEapMethods)) { |
||
| 206 | $this->selectedEap = $eap->getArrayRep(); |
||
| 207 | break; |
||
| 208 | } |
||
| 209 | } |
||
| 210 | if ($this->selectedEap != []) { |
||
| 211 | $this->selectedEapObject = new common\EAP($this->selectedEap); |
||
| 212 | } |
||
| 213 | } |
||
| 214 | |||
| 215 | /** |
||
| 216 | * prepare usage information for the installer |
||
| 217 | * every device module should override this method |
||
| 218 | * |
||
| 219 | * @return string HTML text to be displayed |
||
| 220 | */ |
||
| 221 | public function writeDeviceInfo() { |
||
| 222 | common\Entity::intoThePotatoes(); |
||
| 223 | $retval = _("Sorry, this should not happen - no additional information is available"); |
||
| 224 | common\Entity::outOfThePotatoes(); |
||
| 225 | return $retval; |
||
| 226 | } |
||
| 227 | |||
| 228 | /** |
||
| 229 | * function to return exactly one attribute type |
||
| 230 | * |
||
| 231 | * @param string $attrName the attribute to retrieve |
||
| 232 | * @return array|NULL the attributes |
||
| 233 | */ |
||
| 234 | public function getAttribute($attrName) { |
||
| 236 | } |
||
| 237 | |||
| 238 | /** |
||
| 239 | * some modules have a complex directory structure. This helper finds resources |
||
| 240 | * in that structure. Mostly used in the Windows modules. |
||
| 241 | * |
||
| 242 | * @param string $file the filename to search for (without path) |
||
| 243 | * @return string|boolean the filename as found, with path, or FALSE if it does not exist |
||
| 244 | */ |
||
| 245 | private function findSourceFile($file) { |
||
| 246 | if (is_file($this->module_path . '/Files/' . $this->device_id . '/' . $file)) { |
||
| 247 | return $this->module_path . '/Files/' . $this->device_id . '/' . $file; |
||
| 248 | } elseif (is_file($this->module_path . '/Files/' . $file)) { |
||
| 249 | return $this->module_path . '/Files/' . $file; |
||
| 250 | } else { |
||
| 251 | $this->loggerInstance->debug(2, "requested file $file does not exist\n"); |
||
| 252 | return FALSE; |
||
| 253 | } |
||
| 254 | } |
||
| 255 | |||
| 256 | /** |
||
| 257 | * Copy a file from the module location to the temporary directory. |
||
| 258 | * |
||
| 259 | * If the second argument is provided then the file will be saved under the name |
||
| 260 | * taken form this argument. If only one parameter is given, source and destination |
||
| 261 | * filenames are the same |
||
| 262 | * Source file can be located either in the Files subdirectory or in the sibdirectory of Files |
||
| 263 | * named the same as device_id. The second option takes precedence. |
||
| 264 | * |
||
| 265 | * @param string $source_name The source file name |
||
| 266 | * @param string $output_name The destination file name |
||
| 267 | * |
||
| 268 | * @return boolean result of the copy operation |
||
| 269 | * @final not to be redefined |
||
| 270 | */ |
||
| 271 | final protected function copyFile($source_name, $output_name = NULL) { |
||
| 286 | } |
||
| 287 | |||
| 288 | /** |
||
| 289 | * Copy a file from the module location to the temporary directory aplying transcoding. |
||
| 290 | * |
||
| 291 | * Transcoding is only required for Windows installers, and no Unicode support |
||
| 292 | * in NSIS (NSIS version below 3) |
||
| 293 | * Trancoding is only applied if the third optional parameter is set and nonzero |
||
| 294 | * If CONFIG['NSIS']_VERSION is set to 3 or more, no transcoding will be applied |
||
| 295 | * regardless of the third parameter value. |
||
| 296 | * If the second argument is provided and is not equal to 0, then the file will be |
||
| 297 | * saved under the name taken from this argument. |
||
| 298 | * If only one parameter is given or the second is equal to 0, source and destination |
||
| 299 | * filenames are the same. |
||
| 300 | * The third optional parameter, if nonzero, should be the character set understood by iconv |
||
| 301 | * This is required by the Windows installer and is expected to go away in the future. |
||
| 302 | * Source file can be located either in the Files subdirectory or in the sibdirectory of Files |
||
| 303 | * named the same as device_id. The second option takes precedence. |
||
| 304 | * |
||
| 305 | * @param string $source_name The source file name |
||
| 306 | * @param string $output_name The destination file name |
||
| 307 | * @param int $encoding Set Windows charset if non-zero |
||
| 308 | * @return boolean |
||
| 309 | * @final not to be redefined |
||
| 310 | */ |
||
| 311 | final protected function translateFile($source_name, $output_name = NULL, $encoding = 0) { |
||
| 312 | // there is no explicit gettext() call in this function, but catalogues |
||
| 313 | // and translations occur in the varios ".inc" files - so make sure we |
||
| 314 | // operate in the correct catalogue |
||
| 315 | common\Entity::intoThePotatoes(); |
||
| 316 | if (CONFIG_CONFASSISTANT['NSIS_VERSION'] >= 3) { |
||
| 317 | $encoding = 0; |
||
| 318 | } |
||
| 319 | if ($output_name === NULL) { |
||
| 320 | $output_name = $source_name; |
||
| 321 | } |
||
| 322 | |||
| 323 | $this->loggerInstance->debug(5, "translateFile($source_name, $output_name, $encoding)\n"); |
||
| 324 | ob_start(); |
||
| 325 | $this->loggerInstance->debug(5, $this->module_path . '/Files/' . $this->device_id . '/' . $source_name . "\n"); |
||
| 326 | $source = $this->findSourceFile($source_name); |
||
| 327 | |||
| 328 | if ($source !== FALSE) { // if there is no file found, don't attempt to include an uninitialised variable |
||
| 329 | include $source; |
||
| 330 | } |
||
| 331 | $output = ob_get_clean(); |
||
| 332 | if ($encoding) { |
||
| 333 | $outputClean = iconv('UTF-8', $encoding . '//TRANSLIT', $output); |
||
| 334 | if ($outputClean) { |
||
| 335 | $output = $outputClean; |
||
| 336 | } |
||
| 337 | } |
||
| 338 | $fileHandle = fopen("$output_name", "w"); |
||
| 339 | if ($fileHandle === FALSE) { |
||
| 340 | $this->loggerInstance->debug(2, "translateFile($source, $output_name, $encoding) failed\n"); |
||
| 341 | common\Entity::outOfThePotatoes(); |
||
| 342 | return FALSE; |
||
| 343 | } |
||
| 344 | fwrite($fileHandle, $output); |
||
| 345 | fclose($fileHandle); |
||
| 346 | $this->loggerInstance->debug(5, "translateFile($source, $output_name, $encoding) end\n"); |
||
| 347 | common\Entity::outOfThePotatoes(); |
||
| 348 | return TRUE; |
||
| 349 | } |
||
| 350 | |||
| 351 | /** |
||
| 352 | * Transcode a string adding double quotes escaping |
||
| 353 | * |
||
| 354 | * Transcoding is only required for Windows installers, and no Unicode support |
||
| 355 | * in NSIS (NSIS version below 3) |
||
| 356 | * Trancoding is only applied if the third optional parameter is set and nonzero |
||
| 357 | * If CONFIG['NSIS']_VERSION is set to 3 or more, no transcoding will be applied |
||
| 358 | * regardless of the second parameter value. |
||
| 359 | * The second optional parameter, if nonzero, should be the character set understood by iconv |
||
| 360 | * This is required by the Windows installer and is expected to go away in the future. |
||
| 361 | * |
||
| 362 | * @param string $source_string The source string |
||
| 363 | * @param int $encoding Set Windows charset if non-zero |
||
| 364 | * @return string |
||
| 365 | * @final not to be redefined |
||
| 366 | */ |
||
| 367 | final protected function translateString($source_string, $encoding = 0) { |
||
| 368 | $this->loggerInstance->debug(5, "translateString input: \"$source_string\"\n"); |
||
| 369 | if (empty($source_string)) { |
||
| 370 | return $source_string; |
||
| 371 | } |
||
| 372 | if (CONFIG_CONFASSISTANT['NSIS_VERSION'] >= 3) { |
||
| 373 | $encoding = 0; |
||
| 374 | } |
||
| 375 | if ($encoding) { |
||
| 376 | $output_c = iconv('UTF-8', $encoding . '//TRANSLIT', $source_string); |
||
| 377 | } else { |
||
| 378 | $output_c = $source_string; |
||
| 379 | } |
||
| 380 | if ($output_c) { |
||
| 381 | $source_string = str_replace('"', '$\\"', $output_c); |
||
| 382 | } else { |
||
| 383 | $this->loggerInstance->debug(2, "Failed to convert string \"$source_string\"\n"); |
||
| 384 | } |
||
| 385 | return $source_string; |
||
| 386 | } |
||
| 387 | |||
| 388 | /** |
||
| 389 | * Save certificate files in either DER or PEM format |
||
| 390 | * |
||
| 391 | * Certificate files will be saved in the module working directory. |
||
| 392 | * |
||
| 393 | * saved certificate file names are avalable under the 'file' index |
||
| 394 | * additional array entries are indexed as 'sha1', 'md5', and 'root'. |
||
| 395 | * sha1 and md5 are correcponding certificate hashes |
||
| 396 | * root is set to 1 for the CA roor certicicate and 0 otherwise |
||
| 397 | * |
||
| 398 | * @param string $format only "der" and "pem" are currently allowed |
||
| 399 | * @return array an array of arrays or empty array on error |
||
| 400 | |||
| 401 | */ |
||
| 402 | final protected function saveCertificateFiles($format) { |
||
| 403 | switch ($format) { |
||
| 404 | case "der": // fall-thorugh, same treatment |
||
| 405 | case "pem": |
||
| 406 | $iterator = 0; |
||
| 407 | $caFiles = []; |
||
| 408 | $caArray = $this->attributes['internal:CAs'][0]; |
||
| 409 | if (!$caArray) { |
||
| 410 | return([]); |
||
| 411 | } |
||
| 412 | foreach ($caArray as $certAuthority) { |
||
| 413 | $fileHandle = fopen("cert-$iterator.crt", "w"); |
||
| 414 | if (!$fileHandle) { |
||
| 415 | throw new Exception("problem opening the file"); |
||
| 416 | } |
||
| 417 | if ($format === "pem") { |
||
| 418 | fwrite($fileHandle, $certAuthority['pem']); |
||
| 419 | } else { |
||
| 420 | fwrite($fileHandle, $certAuthority['der']); |
||
| 421 | } |
||
| 422 | fclose($fileHandle); |
||
| 423 | $certAuthorityProps = []; |
||
| 424 | $certAuthorityProps['file'] = "cert-$iterator.crt"; |
||
| 425 | $certAuthorityProps['sha1'] = $certAuthority['sha1']; |
||
| 426 | $certAuthorityProps['md5'] = $certAuthority['md5']; |
||
| 427 | $certAuthorityProps['root'] = $certAuthority['root']; |
||
| 428 | $caFiles[] = $certAuthorityProps; |
||
| 429 | $iterator++; |
||
| 430 | } |
||
| 431 | return($caFiles); |
||
| 432 | default: |
||
| 433 | $this->loggerInstance->debug(2, 'incorrect format value specified'); |
||
| 434 | return([]); |
||
| 435 | } |
||
| 436 | } |
||
| 437 | |||
| 438 | /** |
||
| 439 | * set of characters to remove from filename strings |
||
| 440 | */ |
||
| 441 | private const TRANSLIT_SCRUB = '/[ ()\/\'"]+/'; |
||
| 442 | |||
| 443 | /** |
||
| 444 | * Does a transliteration from UTF-8 to ASCII to get a sane filename |
||
| 445 | * Takes special characters into account, and always uses English CTYPE |
||
| 446 | * to avoid introduction of funny characters due to "flying accents" |
||
| 447 | * |
||
| 448 | * @param string $input the input string that is to be transliterated |
||
| 449 | * @return string the transliterated string |
||
| 450 | */ |
||
| 451 | private function customTranslit($input) { |
||
| 457 | } |
||
| 458 | |||
| 459 | /** |
||
| 460 | * Generate installer filename base. |
||
| 461 | * Device module should use this name adding an extension. |
||
| 462 | * Normally the device identifier follows the Consortium name. |
||
| 463 | * The sting taken for the device identifier equals (by default) to the index in the listDevices array, |
||
| 464 | * but can be overriden with the 'device_id' device option. |
||
| 465 | * |
||
| 466 | * @return string |
||
| 467 | */ |
||
| 468 | private function getInstallerBasename() { |
||
| 469 | |||
| 470 | $baseName = $this->customTranslit(CONFIG_CONFASSISTANT['CONSORTIUM']['name']) . "-" . $this->getDeviceId(); |
||
| 471 | if (isset($this->attributes['profile:customsuffix'][1])) { |
||
| 472 | // this string will end up as a filename on a filesystem, so always |
||
| 473 | // take a latin-based language variant if available |
||
| 474 | // and then scrub non-ASCII just in case |
||
| 475 | return $baseName . $this->customTranslit($this->attributes['profile:customsuffix'][1]); |
||
| 476 | } |
||
| 477 | // Okay, no custom suffix. |
||
| 478 | // Use the configured inst name and apply shortening heuristics |
||
| 479 | $lang_pointer = CONFIG['LANGUAGES'][$this->languageInstance->getLang()]['latin_based'] == TRUE ? 0 : 1; |
||
| 480 | $this->loggerInstance->debug(5, "getInstallerBasename1:" . $this->attributes['general:instname'][$lang_pointer] . "\n"); |
||
| 481 | $inst = $this->customTranslit($this->attributes['general:instname'][$lang_pointer]); |
||
| 482 | $this->loggerInstance->debug(4, "getInstallerBasename2:$inst\n"); |
||
| 483 | $Inst_a = explode('_', $inst); |
||
| 484 | if (count($Inst_a) > 2) { |
||
| 485 | $inst = ''; |
||
| 486 | foreach ($Inst_a as $i) { |
||
| 487 | $inst .= $i[0]; |
||
| 488 | } |
||
| 489 | } |
||
| 490 | // and if the inst has multiple profiles, add the profile name behin |
||
| 491 | if ($this->attributes['internal:profile_count'][0] > 1) { |
||
| 492 | if (!empty($this->attributes['profile:name']) && !empty($this->attributes['profile:name'][$lang_pointer])) { |
||
| 493 | $profTemp = $this->customTranslit($this->attributes['profile:name'][$lang_pointer]); |
||
| 494 | $prof = preg_replace('/_+$/', '', $profTemp); |
||
| 495 | return $baseName . $inst . '-' . $prof; |
||
| 496 | } |
||
| 497 | } |
||
| 498 | return $baseName . $inst; |
||
| 499 | } |
||
| 500 | |||
| 501 | /** |
||
| 502 | * returns the device_id of the current device |
||
| 503 | * |
||
| 504 | * @return string |
||
| 505 | */ |
||
| 506 | private function getDeviceId() { |
||
| 515 | } |
||
| 516 | |||
| 517 | /** |
||
| 518 | * returns the list of SSIDs that installers should treat. |
||
| 519 | * |
||
| 520 | * Includes both SSIDs to be set up (and whether it's a TKIP-mixed or AES-only SSID) and SSIDs to be deleted |
||
| 521 | * |
||
| 522 | * @return array |
||
| 523 | */ |
||
| 524 | private function getSSIDs() { |
||
| 525 | $ssidList = []; |
||
| 526 | $ssidList['add'] = []; |
||
| 527 | $ssidList['del'] = []; |
||
| 528 | if (isset(CONFIG_CONFASSISTANT['CONSORTIUM']['ssid'])) { |
||
| 529 | foreach (CONFIG_CONFASSISTANT['CONSORTIUM']['ssid'] as $ssid) { |
||
| 530 | if (\core\common\Entity::getAttributeValue(CONFIG_CONFASSISTANT, 'CONSORTIUM', 'tkipsupport') == TRUE) { |
||
| 531 | $ssidList['add'][$ssid] = 'TKIP'; |
||
| 532 | } else { |
||
| 533 | $ssidList['add'][$ssid] = 'AES'; |
||
| 534 | $ssidList['del'][$ssid] = 'TKIP'; |
||
| 535 | } |
||
| 536 | } |
||
| 537 | } |
||
| 538 | if (isset($this->attributes['media:SSID'])) { |
||
| 539 | $ssidWpa2 = $this->attributes['media:SSID']; |
||
| 540 | |||
| 541 | foreach ($ssidWpa2 as $ssid) { |
||
| 542 | $ssidList['add'][$ssid] = 'AES'; |
||
| 543 | } |
||
| 544 | } |
||
| 545 | if (isset($this->attributes['media:SSID_with_legacy'])) { |
||
| 546 | $ssidTkip = $this->attributes['media:SSID_with_legacy']; |
||
| 547 | foreach ($ssidTkip as $ssid) { |
||
| 548 | $ssidList['add'][$ssid] = 'TKIP'; |
||
| 549 | } |
||
| 550 | } |
||
| 551 | if (isset($this->attributes['media:remove_SSID'])) { |
||
| 552 | $ssidRemove = $this->attributes['media:remove_SSID']; |
||
| 553 | foreach ($ssidRemove as $ssid) { |
||
| 554 | $ssidList['del'][$ssid] = 'DEL'; |
||
| 555 | } |
||
| 556 | } |
||
| 557 | return $ssidList; |
||
| 558 | } |
||
| 559 | |||
| 560 | /** |
||
| 561 | * returns the list of Hotspot 2.0 / Passpoint roaming consortia to set up |
||
| 562 | * |
||
| 563 | * @return array |
||
| 564 | */ |
||
| 565 | private function getConsortia() { |
||
| 578 | } |
||
| 579 | |||
| 580 | /** |
||
| 581 | * An array with shorthand definitions for MIME types |
||
| 582 | * @var array |
||
| 583 | */ |
||
| 584 | private $mime_extensions = [ |
||
| 585 | 'text/plain' => 'txt', |
||
| 586 | 'text/rtf' => 'rtf', |
||
| 587 | 'application/pdf' => 'pdf', |
||
| 588 | ]; |
||
| 589 | |||
| 590 | /** |
||
| 591 | * saves a number of logos to a cache directory on disk. |
||
| 592 | * |
||
| 593 | * @param array $logos list of logos (binary strings each) |
||
| 594 | * @param string $type a qualifier what type of logo this is |
||
| 595 | * @return array list of filenames and the mime types |
||
| 596 | * @throws Exception |
||
| 597 | */ |
||
| 598 | private function saveLogoFile($logos,$type) { |
||
| 623 | } |
||
| 624 | |||
| 625 | /** |
||
| 626 | * saves the Terms of Use file onto disk |
||
| 627 | * |
||
| 628 | * @param string $blob the Terms of Use |
||
| 629 | * @return array with one entry, containging the filename and mime type |
||
| 630 | * @throws Exception |
||
| 631 | */ |
||
| 632 | private function saveInfoFile($blob) { |
||
| 633 | $finfo = new \finfo(FILEINFO_MIME_TYPE); |
||
| 634 | $mime = $finfo->buffer($blob); |
||
| 635 | $ext = isset($this->mime_extensions[$mime]) ? $this->mime_extensions[$mime] : 'usupported'; |
||
| 636 | $this->loggerInstance->debug(5, "saveInfoFile: $mime : $ext\n"); |
||
| 637 | $fileHandle = fopen('local-info.' . $ext, "w"); |
||
| 638 | if ($fileHandle === FALSE) { |
||
| 639 | throw new Exception("problem opening the file"); |
||
| 640 | } |
||
| 641 | fwrite($fileHandle, $blob); |
||
| 642 | fclose($fileHandle); |
||
| 643 | return(['name' => 'local-info.' . $ext, 'mime' => $ext]); |
||
| 644 | } |
||
| 645 | |||
| 646 | /** |
||
| 647 | * returns the attributes of the profile for which to generate an installer |
||
| 648 | * |
||
| 649 | * In condensed notion, and most specific level only (i.e. ignores overriden attributes from a higher level) |
||
| 650 | * @param \core\AbstractProfile $profile the Profile in question |
||
| 651 | * @return array |
||
| 652 | */ |
||
| 653 | private function getProfileAttributes(AbstractProfile $profile) { |
||
| 654 | $bestMatchEap = $this->selectedEap; |
||
| 655 | if (count($bestMatchEap) > 0) { |
||
| 656 | $a = $profile->getCollapsedAttributes($bestMatchEap); |
||
| 657 | $a['eap'] = $bestMatchEap; |
||
| 658 | $a['all_eaps'] = $profile->getEapMethodsinOrderOfPreference(1); |
||
| 659 | return($a); |
||
| 660 | } |
||
| 661 | print("No supported eap types found for this profile.\n"); |
||
| 662 | return []; |
||
| 663 | } |
||
| 664 | |||
| 665 | /** |
||
| 666 | * dumps attributes for debugging purposes |
||
| 667 | * |
||
| 668 | * dumpAttibutes method is supplied for debuging purposes, it simply dumps the attribute array |
||
| 669 | * to a file with name passed in the attribute. |
||
| 670 | * @param string $file the output file name |
||
| 671 | * @return void |
||
| 672 | */ |
||
| 673 | protected function dumpAttibutes($file) { |
||
| 674 | ob_start(); |
||
| 675 | print_r($this->attributes); |
||
| 676 | $output = ob_get_clean(); |
||
| 677 | file_put_contents($file, $output); |
||
| 678 | } |
||
| 679 | |||
| 680 | /** |
||
| 681 | * placeholder for the main device method |
||
| 682 | * @return string |
||
| 683 | */ |
||
| 684 | abstract public function writeInstaller(); |
||
| 685 | |||
| 686 | /** |
||
| 687 | * collates the string to use as EAP outer ID |
||
| 688 | * |
||
| 689 | * @return string|NULL |
||
| 690 | */ |
||
| 691 | protected function determineOuterIdString() { |
||
| 700 | } |
||
| 701 | |||
| 702 | /** |
||
| 703 | * Array passing all options to the device module. |
||
| 704 | * |
||
| 705 | * $attrbutes array contains option values defined for the institution and a particular |
||
| 706 | * profile (possibly overriding one another) ready for the device module to consume. |
||
| 707 | * |
||
| 708 | * For each of the options the value is another array of vales (even if only one value is present). |
||
| 709 | * Some attributes may be missing if they have not been configured for a viven institution or profile. |
||
| 710 | * |
||
| 711 | * The following attributes are meant to be used by device modules: |
||
| 712 | * - <b>general:geo_coordinates</b> - geographical coordinates of the institution or a campus |
||
| 713 | * - <b>support:info_file</b> - consent file displayed to the users |
||
| 714 | * - <b>general:logo_file</b> - file data containing institution logo |
||
| 715 | * - <b>support:eap_types</b> - URL to a local support page for a specific eap methiod, not to be confused with general:url |
||
| 716 | * - <b>support:email</b> - email for users to contact for local instructions |
||
| 717 | * - <b>support:phone</b> - telephone number for users to contact for local instructions |
||
| 718 | * - <b>support:url</b> - URL where the user will find local instructions |
||
| 719 | * - <b>internal:info_file</b> - the pathname of the info_file saved in the working directory |
||
| 720 | * - <b>internal:logo_file</b> - array of pathnames of logo_files saved in the working directory |
||
| 721 | * - <b>internal:CAs</b> - the value is an array produced by X509::processCertificate() with the following filds |
||
| 722 | * - <b>internal:SSID</b> - an array indexed by SSID strings with values either TKIP or AES; if TKIP is set the both WPA/TKIP and WPA2/AES should be set if AES is set the this is a WPA2/AES only SSID; the consortium's defined SSIDs are always set as the first array elements. |
||
| 723 | * - <b>internal:consortia</b> an array of consortion IO as declared in the config-confassistant |
||
| 724 | * - <b>internal:profile_count</b> - the number of profiles for the associated IdP |
||
| 725 | * |
||
| 726 | * |
||
| 727 | * these attributes are available and can be used, but the "internal" attributes are better suited for modules |
||
| 728 | * - eap:ca_file - certificate of the CA signing the RADIUS server key |
||
| 729 | * - <b>media:SSID</b> - additional SSID to configure, WPA2/AES only (device modules should use internal:SSID) |
||
| 730 | * - <b>media:SSID_with_legacy</b> - additional SSID to configure, WPA2/AES and WPA/TKIP (device modules should use internal:SSID) |
||
| 731 | * |
||
| 732 | * @see \core\common\X509::processCertificate() |
||
| 733 | * @var array $attributes |
||
| 734 | */ |
||
| 735 | public $attributes; |
||
| 736 | |||
| 737 | /** |
||
| 738 | * stores the path to the module source location and is used |
||
| 739 | * by copyFile and translateFile |
||
| 740 | * the only reason for it to be a public variable ies that it is set by the DeviceFactory class |
||
| 741 | * module_path should not be used by module drivers. |
||
| 742 | * @var string |
||
| 743 | */ |
||
| 744 | public $module_path; |
||
| 745 | |||
| 746 | /** |
||
| 747 | * * The optimal EAP type selected given profile and device |
||
| 748 | * @var array |
||
| 749 | */ |
||
| 750 | public $selectedEap; |
||
| 751 | public $selectedEapObject; |
||
| 752 | |||
| 753 | /** |
||
| 754 | * the path to the profile signing program |
||
| 755 | * device modules which require signing should use this property to exec the signer |
||
| 756 | * the signer program must accept two arguments - input and output file names |
||
| 757 | * the signer program mus operate in the local directory and filenames are relative to this |
||
| 758 | * directory |
||
| 759 | * |
||
| 760 | * @var string |
||
| 761 | */ |
||
| 762 | public $sign; |
||
| 763 | public $signer; |
||
| 764 | |||
| 765 | /** |
||
| 766 | * The string identifier of the device (don't show this to users) |
||
| 767 | * @var string |
||
| 768 | */ |
||
| 769 | public $device_id; |
||
| 770 | |||
| 771 | /** |
||
| 772 | * See devices-template.php for a list of available options |
||
| 773 | * @var array |
||
| 774 | */ |
||
| 775 | public $options; |
||
| 776 | |||
| 777 | /** |
||
| 778 | * This string will be shown if no support email was configured by the admin |
||
| 779 | * |
||
| 780 | * @var string |
||
| 781 | */ |
||
| 782 | public $support_email_substitute; |
||
| 783 | |||
| 784 | /** |
||
| 785 | * This string will be shown if no support URL was configured by the admin |
||
| 786 | * |
||
| 787 | * @var string |
||
| 788 | */ |
||
| 789 | public $support_url_substitute; |
||
| 790 | |||
| 791 | /** |
||
| 792 | * This string should be used by all installer modules to set the |
||
| 793 | * installer file basename. |
||
| 794 | * |
||
| 795 | * @var string |
||
| 796 | */ |
||
| 797 | public $installerBasename; |
||
| 798 | |||
| 799 | /** |
||
| 800 | * stores the PKCS#12 DER representation of a client certificate for SilverBullet |
||
| 801 | */ |
||
| 802 | protected $clientCert; |
||
| 803 | |||
| 804 | /** |
||
| 805 | * stores identifier used by GEANTLink profiles |
||
| 806 | */ |
||
| 807 | public $deviceUUID; |
||
| 808 | |||
| 810 |