Skip to content

Commit

Permalink
Added UI for MOK enrollment
Browse files Browse the repository at this point in the history
Added UI for MOK enrollment
  • Loading branch information
MoizAdnan committed Aug 1, 2023
2 parents fbf5fc1 + e2e1851 commit 880a489
Show file tree
Hide file tree
Showing 12 changed files with 347 additions and 41 deletions.
49 changes: 19 additions & 30 deletions assets/scripts/check-mok.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,20 @@ set -e
# Parameters
#===========

PASSWORD=$1

#==========
# Functions
#==========

enrollMok() {
password=$1

sudo dpkg --configure -a

echo -e "\n\n\n"
echo -e "The system needs to restart. After booting, you will be presented\n with the MOK Manager. In MOK Manager select 'Enroll MOK' and continue.\n
Enter the password you just entered when asked by the MOK Manager.\n After the process is complete, click 'Reboot'.\n
After booting run Ethereal Engine Control Center."
read -p "Do you want to restart the system? (y/n) " yn

case $yn in
y ) echo Restarting...;;
n ) echo Exiting...;
exit 1;;
* ) echo invalid response;
exit 1;;
while getopts o:p: flag; do
case "${flag}" in
p) PASSWORD=${OPTARG} ;;
*)
echo "Invalid argument passed" >&2
exit 1
;;
esac
done

echo "$password" | sudo -S systemctl reboot
exit 0
}

export -f enrollMok
if [[ -z $PASSWORD ]]; then
echo "Missing arguments"
exit 1
fi

#===========
# Verify MOK
Expand All @@ -52,10 +36,15 @@ else
fi

if echo "$PASSWORD" | sudo -S mokutil --sb-state | grep -q 'SecureBoot enabled'; then
echo "Secureboot is enabled"
if echo "$PASSWORD" | sudo -S mokutil --list-enrolled | grep -q 'Secure Boot Module Signature key'; then
echo "mok is enrolled"
exit 0
else
gnome-terminal --wait -- bash -c "enrollMok $PASSWORD;exec bash"

echo "mok is not enrolled"
#Exit code 2 indicates permission is needed
exit 2
fi
else
echo "SecureBoot is disabled"
fi
10 changes: 1 addition & 9 deletions assets/scripts/configure-minikube-linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,6 @@ checkExitCode

set -e

#===========
# Verify MOK
#===========

bash "$SCRIPTS_FOLDER/check-mok.sh" "$PASSWORD"

checkExitCode

#=============
# Verify Node
#=============
Expand Down Expand Up @@ -184,7 +176,7 @@ else
echo "virtualbox-dkms is not installed"

echo "$PASSWORD" | sudo -S apt update -y
echo "$PASSWORD" | sudo -S sudo apt-get install virtualbox-dkms
echo "$PASSWORD" | sudo -S sudo apt-get install -y virtualbox-dkms
fi

#==================
Expand Down
2 changes: 1 addition & 1 deletion release/app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "etherealengine-control-center",
"version": "0.3.5",
"version": "0.3.6",
"description": "A desktop app for managing Ethereal Engine cluster.",
"license": "MIT",
"author": {
Expand Down
3 changes: 2 additions & 1 deletion src/constants/Channels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ const Channels = {
ConfigureK8Dashboard: 'ConfigureK8Dashboard',
ConfigureK8DashboardError: 'ConfigureK8DashboardError',
ConfigureK8DashboardResponse: 'ConfigureK8DashboardResponse',
ConfigureCluster: 'ConfigureCluster'
ConfigureCluster: 'ConfigureCluster',
PromptSetupMok: 'PromptSetupMok'
},
Updates: {
CheckUpdate: 'CheckUpdate',
Expand Down
2 changes: 2 additions & 0 deletions src/main/Clusters/BaseCluster/BaseCluster.commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ const Commands = {
DOCKER_STATS: "docker system df --format='{{json .}}';",
DOCKER_PRUNE: 'docker system prune -a -f;',
DEPLOYMENT_PRUNE: 'helm uninstall agones local-redis local;',
MOK_SETUP: 'gnome-terminal --wait -- bash -c "sudo dpkg --configure -a; exit 0; exec bash"',
MOK_RESTART: `sudo systemctl reboot`,
STATUS_CHECK_BATCH_LIMIT: 2
}

Expand Down
16 changes: 16 additions & 0 deletions src/main/Clusters/Minikube/Minikube.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,22 @@ class Minikube {

const scriptsFolder = scriptsPath()
const assetsFolder = assetsPath()

const checkMokScript = path.join(scriptsFolder, 'check-mok.sh')
log.info(`Executing script ${checkMokScript}`)

const onCheckMokStd = (data: any) => {
window.webContents.send(Channels.Utilities.Log, cluster.id, { category, message: data } as LogModel)
}
const mokCode = await execStreamScriptFile(checkMokScript, [`-p "${password}"`], onCheckMokStd, onCheckMokStd)

if (mokCode === 1) {
throw `Failed with error code ${mokCode}.`
} else if (mokCode === 2) {
window.webContents.send(Channels.Cluster.PromptSetupMok, cluster)
return
}

const configureScript = path.join(scriptsFolder, 'configure-minikube-linux.sh')
log.info(`Executing script ${configureScript}`)

Expand Down
7 changes: 7 additions & 0 deletions src/renderer/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -234,4 +234,11 @@ body {

.font-14 {
font-size: 14px !important;
}

.textEllipse {
white-space: nowrap;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
}
8 changes: 8 additions & 0 deletions src/renderer/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import HotBar from './common/HotBar'
import NavView from './common/NavView'
import { defaultAction } from './common/NotistackActions'
import AuthenticationDialog from './dialogs/AuthenticationDialog'
import MokEnrollDialog from './dialogs/MokEnrollDialog'
import MokRestartDialog from './dialogs/MokRestartDialog'
import AdminPage from './pages/AdminPage'
import ConfigPage from './pages/ConfigPage'
import IPFSPage from './pages/IPFSPage'
Expand All @@ -33,6 +35,8 @@ const App = () => {

const settingsState = useSettingsState()
const { showAuthenticationDialog } = settingsState.value
const { mokEnrollCluster } = settingsState.value
const { mokRestartCluster } = settingsState.value

const defaultMode = 'vaporwave' as ThemeMode
const storedMode = localStorage.getItem(Storage.COLOR_MODE) as ThemeMode | undefined
Expand Down Expand Up @@ -108,6 +112,10 @@ const App = () => {
{showAuthenticationDialog && (
<AuthenticationDialog onClose={() => SettingsService.setAuthenticationDialog(false)} />
)}
{mokEnrollCluster && <MokEnrollDialog onClose={() => SettingsService.setMokEnrollCluster(undefined)} />}
{mokRestartCluster && (
<MokRestartDialog onClose={() => SettingsService.setMokRestartCluster(undefined)} />
)}
</Box>
</HashRouter>
</SnackbarProvider>
Expand Down
121 changes: 121 additions & 0 deletions src/renderer/dialogs/MokEnrollDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import Channels from 'constants/Channels'
import Commands from 'main/Clusters/BaseCluster/BaseCluster.commands'
import { cloneCluster } from 'models/Cluster'
import { ShellResponse } from 'models/ShellResponse'
import { enqueueSnackbar } from 'notistack'
import { SettingsService, useSettingsState } from 'renderer/services/SettingsService'

import { Avatar, Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, Typography } from '@mui/material'

import logoMinikube from '../../../assets/icons/minikube.png'

interface Props {
onClose: () => void
}

const MokEnrollDialog = ({ onClose }: Props) => {
const settingsState = useSettingsState()
const selectedCluster = settingsState.value.mokEnrollCluster

const onSetupMok = async () => {
try {
const clonedCluster = cloneCluster(selectedCluster!)

const output: ShellResponse = await window.electronAPI.invoke(
Channels.Shell.ExecuteCommand,
clonedCluster,
Commands.MOK_SETUP
)

const stringError = output.stderr?.toString().trim() || ''
if (stringError.toLowerCase().includes('error')) {
throw stringError
}

onClose()
SettingsService.setMokRestartCluster(clonedCluster)
} catch (err) {
enqueueSnackbar('Failed to setup MOK.', { variant: 'error' })
}
}

return (
<Dialog open fullWidth maxWidth="sm" scroll="paper">
<DialogTitle>Machine Owner Key (MOK) enrollment</DialogTitle>
<DialogContent dividers sx={{ padding: 0 }}>
<Box
sx={{
display: 'flex',
flexDirection: 'column',
mb: 2,
ml: 3,
mr: 3,
mt: 2
}}
>
<Box sx={{ display: 'flex', alignItems: 'flex-start', flexDirection: 'row', justifyContent: 'center' }}>
<Box
sx={{
height: '100%',
maxWidth: 80,
flexDirection: 'column',
display: 'flex',
alignItems: 'center',
paddingRight: 2,
gap: 1
}}
>
<Box sx={{ width: 45 }} component="img" src={logoMinikube} />
<Typography variant="body1" title={selectedCluster?.name} className="textEllipse">
{selectedCluster?.name}
</Typography>
</Box>
<Box sx={{ display: 'flex', alignItems: 'flex-start', flexDirection: 'column' }}>
<Typography variant="body2">
UEFI Secure Boot is enabled for this system. You need a Secure Boot Module Signature key enrolled for
Minikube configuration to proceed. Once you allow this app to enroll this Machine Owner Key, you will be
presented with a terminal.
</Typography>
</Box>
</Box>
<Box sx={{ display: 'flex', alignItems: 'center', flexDirection: 'row' }}>
<Typography variant="body2" sx={{ marginTop: 2 }}>
Please follow these steps in the terminal to create a Secure Boot Module Signature key for your system:
</Typography>
</Box>
<Box sx={{ ml: 1.5, mt: 2 }}>
<Box sx={{ display: 'flex', alignItems: 'center', flexDirection: 'row' }}>
<Avatar sx={{ width: 30, height: 30, fontSize: 16, bgcolor: 'var(--panelBackground)', mr: 1 }}>1</Avatar>
<Typography variant="body2">Enter sudo password</Typography>
</Box>
<Box sx={{ display: 'flex', alignItems: 'center', flexDirection: 'row', mt: 1 }}>
<Avatar sx={{ width: 30, height: 30, fontSize: 16, bgcolor: 'var(--panelBackground)', mr: 1 }}>2</Avatar>
<Typography variant="body2">In the 'Secure Boot' screen, press 'Escape' key</Typography>
</Box>
<Box sx={{ display: 'flex', alignItems: 'center', flexDirection: 'row', mt: 1 }}>
<Avatar sx={{ width: 30, height: 30, fontSize: 16, bgcolor: 'var(--panelBackground)', mr: 1 }}>3</Avatar>
<Typography variant="body2">Enter password for MOK management</Typography>
</Box>
<Box sx={{ display: 'flex', alignItems: 'center', flexDirection: 'row', mt: 1 }}>
<Avatar sx={{ width: 30, height: 30, fontSize: 16, bgcolor: 'var(--panelBackground)', mr: 1 }}>4</Avatar>
<Typography variant="body2">Confirm password for MOK management</Typography>
</Box>
</Box>
<Box sx={{ display: 'flex', alignItems: 'flex-start', flexDirection: 'column', mt: 1 }}>
<Typography variant="body2" sx={{ marginTop: 2, fontWeight: 600 }}>
Do you want to enroll Machine Owner Key?
</Typography>
</Box>
</Box>
</DialogContent>
<DialogActions>
<Button onClick={onClose}>Cancel</Button>
<Button type="submit" onClick={onSetupMok}>
Yes
</Button>
</DialogActions>
</Dialog>
)
}

export default MokEnrollDialog
Loading

0 comments on commit 880a489

Please sign in to comment.