diff options
Diffstat (limited to 'modules-available/serversetup-bwlp-ipxe/api.inc.php')
-rw-r--r-- | modules-available/serversetup-bwlp-ipxe/api.inc.php | 319 |
1 files changed, 52 insertions, 267 deletions
diff --git a/modules-available/serversetup-bwlp-ipxe/api.inc.php b/modules-available/serversetup-bwlp-ipxe/api.inc.php index c3804a03..dc78f481 100644 --- a/modules-available/serversetup-bwlp-ipxe/api.inc.php +++ b/modules-available/serversetup-bwlp-ipxe/api.inc.php @@ -1,273 +1,58 @@ <?php -// Menu mode - -$serverIp = Property::getServerIp(); - -// Check if required arguments are given; if not, spit out according script and chain to self -$uuid = Request::any('uuid', false, 'string'); -// Get platform - EFI or PCBIOS -$platform = Request::any('platform', false, 'string'); -$manuf = Request::any('manuf', false, 'string'); -$product = Request::any('product', false, 'string'); -$slxExtensions = Request::any('slx-extensions', false, 'int'); - -if ($platform === false || ($uuid === false && $product === false) || $slxExtensions === false) { - // Redirect to self with added parameters - $url = parse_url($_SERVER['REQUEST_URI']); - if (isset($_SERVER['SCRIPT_URI']) && preg_match('#^(\w+://[^/]+)#', $_SERVER['SCRIPT_URI'], $out)) { - $urlbase = $out[1]; - } elseif (isset($_SERVER['REQUEST_SCHEME']) && isset($_SERVER['SERVER_NAME'])) { - $urlbase = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME']; - } elseif (isset($_SERVER['REQUEST_SCHEME']) && isset($_SERVER['SERVER_ADDR'])) { - $urlbase = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_ADDR']; - } else { - $urlbase = 'http://' . $serverIp; - } - $urlbase .= $url['path']; - if (empty($url['query'])) { - $arr = []; - } else { - parse_str($url['query'], $arr); - foreach ($arr as &$v) { - $v = urlencode($v); +(function() { + $type = Request::any('type', null, 'string'); + if ($type === null && isset($_SERVER['HTTP_USER_AGENT'])) { + if (preg_match('/^iPXE/', $_SERVER['HTTP_USER_AGENT'])) { + $type = 'ipxe'; + } elseif (preg_match('/^GRUB/', $_SERVER['HTTP_USER_AGENT'])) { + $type = 'grub'; + } elseif (preg_match('/wget|curl/i', $_SERVER['HTTP_USER_AGENT'])) { + $type = 'bash'; } - unset($v); - } - $arr['uuid'] = '${uuid}'; - $arr['mac'] = '${mac}'; - $arr['manuf'] = '${manufacturer:uristring}'; - $arr['product'] = '${product:uristring}'; - $arr['platform'] = '${platform:uristring}'; - $query = '?'; - foreach ($arr as $k => $v) { - $query .= $k . '=' . $v . '&'; - } - //$query = substr($query, 0, -1); - echo <<<HERE -#!ipxe -set slxtest:string something || -iseq \${slxtest:md5} \${} && set slxext 0 || set slxext 1 || -clear slxtest || -set self {$urlbase}{$query}slx-extensions=\${slxext} -:retry -echo Chaining to \${self} -chain -ar \${self} || -echo Chaining to self failed with \${errno}, retrying in a bit... -sleep 5 -goto retry -HERE; - exit; -} -// ipxe has it lowercase, but we use uppercase -$platform = strtoupper($platform); -if ($platform !== 'PCBIOS' && $platform !== 'EFI') { - $platform = 'PCBIOS'; // Just hope for the best? -} - -$BOOT_METHODS = Localboot::BOOT_METHODS[$platform]; - -$ip = $_SERVER['REMOTE_ADDR']; -if (substr($ip, 0, 7) === '::ffff:') { - $ip = substr($ip, 7); -} -$menu = Request::get('menuid', false, 'int'); -if ($menu !== false) { - $menu = new IPxeMenu($menu); - $initLabel = 'slx_menu'; -} else { - $menu = IPxeMenu::forClient($ip, $uuid); - $initLabel = 'init'; -} -// If this is a menu with a single item, treat a timeout of 0 as "boot immediately" instead of "infinite" -if ($menu->itemCount() === 1 && $menu->timeoutMs() === 0 && ($tmp = $menu->getDefaultScriptLabel()) !== false) { - $directBoot = "goto $tmp ||"; - $initLabel = 'init'; -} else { - $directBoot = ''; -} - -// Get preferred localboot method, depending on system model -$localboot = false; -$model = false; -if ($uuid !== false && Module::get('statistics') !== false) { - // If we have the machine table, we rather try to look up the system model from there, using the UUID - $row = Database::queryFirst('SELECT systemmodel FROM machine WHERE machineuuid = :uuid', ['uuid' => $uuid]); - if ($row !== false && !empty($row['systemmodel'])) { - $model = $row['systemmodel']; - } -} -if ($model === false) { - // Otherwise use what iPXE sent us - function modfilt($str) - { - if (empty($str) || preg_match('/product\s+name|be\s+filled|unknown|default\s+string|system\s+model|manufacturer/i', $str)) - return false; - return trim(preg_replace('/\s+/', ' ', $str)); } - $manuf = modfilt($manuf); - $product = modfilt($product); - if (!empty($product)) { - $model = $product; - if (!empty($manuf)) { - $model .= " ($manuf)"; + if ($type === 'bash') { + $builder = new ScriptBuilderBash(); + } elseif ($type === 'grub') { + $builder = new ScriptBuilderGrub(); + } else { + $builder = new ScriptBuilderIpxe(); + } + $bootEntryId = Request::get('beid', false, 'string'); + if ($bootEntryId !== false) { + $bootEntryId = Util::cleanUtf8($bootEntryId); + } + $entryId = Request::get('entryid', false, 'int'); + if ($bootEntryId !== false) { + $entry = BootEntry::fromDatabaseId($bootEntryId); + $data = $builder->getBootEntry($entry); + } elseif ($entryId !== false) { + $entry = MenuEntry::get($entryId); + $data = $builder->getMenuEntry($entry); + } else { + // Get bootstrap code if required... + $data = $builder->bootstrapLive(); + if ($data === false) { + // ...otherwise, generate normal code + $menuId = Request::get('menuid', false, 'int'); + if ($menuId !== false) { + $menu = IPxeMenu::get($menuId, true); + } else { + $menu = IPxeMenu::forClient($builder->clientIp(), $builder->uuid()); + } + $data = null; + if ($menu->itemCount() === 1 && $menu->timeoutMs() === 0) { + // One entry, no timeout -- direct boot + $entry = $menu->defaultEntry(); + if ($entry !== null) { + $data = $builder->getMenuEntry($entry); + } + } + if ($data === null) { + // Show menu + $data = $builder->getMenu($menu, true); + } } } -} -// Query -if ($model !== false) { - $e = strtolower($platform); // We made sure $platform is either PCBIOS or EFI, so no injection possible - $row = Database::queryFirst("SELECT $e AS bootmethod FROM serversetup_localboot WHERE systemmodel = :model LIMIT 1", - ['model' => $model]); - if ($row !== false) { - $localboot = $row['bootmethod']; - } -} -if ($localboot === false || !isset($BOOT_METHODS[$localboot])) { - $localboot = Localboot::getDefault()[$platform]; - if (!isset($BOOT_METHODS[$localboot])) { - $localboot = array_keys($BOOT_METHODS)[0]; - } -} -// Convert to actual ipxe code -if (isset($BOOT_METHODS[$localboot])) { - $localboot = $BOOT_METHODS[$localboot]; -} else { - $localboot = 'prompt Localboot not possible'; -} - -if ($slxExtensions) { - $slxConsoleUpdate = '--update'; - $slxPasswordOnly = '--nouser'; -} else { - $slxConsoleUpdate = ''; - $slxPasswordOnly = ''; -} - -$output = <<<HERE -#!ipxe - -goto $initLabel || goto fail || - -# functions - -# password check with gotos -# set slx_hash to the expected hash -# slx_salt to the salt to use -# slx_pw_ok to the label to jump on success -# slx_pw_fail to label for wrong pw -:slx_pass_check -login $slxPasswordOnly || -set slxtmp_pw \${password:md5}-\${slx_salt} || goto fail -set slxtmp_pw \${slxtmp_pw:md5} || goto fail -clear password || -iseq \${slxtmp_pw} \${slx_hash} || prompt Wrong password. Press a key. || -iseq \${slxtmp_pw} \${slx_hash} || goto \${slx_pw_fail} || -iseq \${slxtmp_pw} \${slx_hash} && goto \${slx_pw_ok} || -goto fail - -:slx_localboot -imgfree || -console || -$localboot || goto fail - -# start -:init - -set ipappend1 ip=\${ip}:{$serverIp}:\${gateway}:\${netmask} -set ipappend2 BOOTIF=01-\${mac:hexhyp} -set serverip $serverIp || -iseq \${idx} \${} && set idx:string X || - -# Clean up in case we've been chained to -imgfree || - -$directBoot - -imgfetch --name bg-menu /tftp/pxe-menu.png || - -:start - -console --left 55 --top 88 --right 63 --bottom 64 --keep --picture bg-menu || - -colour --rgb 0xffffff 7 -colour --rgb 0xcccccc 5 -colour --rgb 0x000000 0 -colour --rgb 0xdddddd 6 -cpair --foreground 0 --background 4 1 -cpair --foreground 0 --background 5 2 -cpair --foreground 7 --background 9 0 - -:slx_menu - -iseq \${serverip} \${} || goto ip_check_ok -goto init -:ip_check_ok - -console --left 55 --top 88 --right 63 --bottom 64 $slxConsoleUpdate --keep --picture bg-menu || - -HERE; - -$output .= $menu->getMenuDefinition('target', $platform, $slxExtensions); - -$output .= <<<HERE - -console --left 60 --top 130 --right 67 --bottom 86 $slxConsoleUpdate || -goto \${target} || -echo Could not find menu entry in script. -prompt Press any key to continue. -goto start - -HERE; - -$output .= $menu->getItemsCode($platform); - -/* - -:i5 -chain -a /tftp/memtest.0 passes=1 onepass || goto membad -prompt Memory OK. Press a key. -goto init - -:i8 -set x:int32 0 -:again -console --left 60 --top 130 --right 67 --bottom 96 --picture bg-load --keep || -console --left 55 --top 88 --right 63 --bottom 64 --picture bg-menu --keep || -inc x -iseq \${x} 20 || goto again -prompt DONE. Press dein Knie. -goto slx_menu - -:membad -iseq \${errno} 0x1 || goto memaborted -params -param scrot \${vram} -imgfetch -a http://132.230.8.113/screen.php##params || -prompt Memory is bad. Press a key. -goto init - -:memaborted -params -param scrot \${vram} -imgfetch -a http://132.230.8.113/screen.php##params || -prompt Memory test aborted. Press a key. -goto init - -*/ - -$output .= <<<HERE -:fail -prompt Boot failed. Press any key to start. -goto init -HERE; - -setlocale(LC_ALL, 'de_DE.UTF-8', 'de_DE.utf-8', 'de_DE.utf8', 'de_DE', 'de', 'German', 'ge', 'en_US.UTF-8', 'en_US.utf-8'); -if ($platform === 'EFI') { - $cs = 'ASCII'; -} else { - $cs = 'IBM437'; -} -Header('Content-Type: text/plain; charset=' . $cs); - -echo iconv('UTF-8', $cs . '//TRANSLIT//IGNORE', $output); + $builder->output($data); +})(); |