aboutsummaryrefslogtreecommitdiffstats
path: root/tools/pygrub/src
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-08-20 16:17:16 +0100
committerKeir Fraser <keir.fraser@citrix.com>2009-08-20 16:17:16 +0100
commitfee98528eaa50c2e554916b9b70795e06b18fbe4 (patch)
tree999728f7ed5a2114710d41c158f4b68edcaa0efd /tools/pygrub/src
parent43639f12e85a20f48b77ffe08f137236e0a20131 (diff)
downloadxen-fee98528eaa50c2e554916b9b70795e06b18fbe4.tar.gz
xen-fee98528eaa50c2e554916b9b70795e06b18fbe4.tar.bz2
xen-fee98528eaa50c2e554916b9b70795e06b18fbe4.zip
pygrub: Add password support
It basically checks for the presence of password line in grub.conf of the guest image and if this line is present, it supports both clear text and md5 versions of the password. Editing the grub entries and command-line are disabled when some password is set in domain's grub.conf file but the password was not entered yet. Also, new option to press 'p' in interactive pygrub has been added to allow entering the grub password. It's been tested on x86_64 with PV guests and was working fine. Also, the countdown has been stopped after key was pressed, ie. the user is probably editing the boot configuration. Signed-off-by: Michal Novotny <minovotn@redhat.com>
Diffstat (limited to 'tools/pygrub/src')
-rw-r--r--tools/pygrub/src/GrubConf.py33
-rw-r--r--tools/pygrub/src/pygrub34
2 files changed, 66 insertions, 1 deletions
diff --git a/tools/pygrub/src/GrubConf.py b/tools/pygrub/src/GrubConf.py
index 2192be6522..55da6f6055 100644
--- a/tools/pygrub/src/GrubConf.py
+++ b/tools/pygrub/src/GrubConf.py
@@ -157,6 +157,7 @@ class GrubConfigFile(object):
self.images = []
self.timeout = -1
self._default = 0
+ self.passwordAccess = True
if fn is not None:
self.parse()
@@ -196,6 +197,7 @@ class GrubConfigFile(object):
if self.commands.has_key(com):
if self.commands[com] is not None:
setattr(self, self.commands[com], arg.strip())
+ #print "%s = %s => %s" % (com, self.commands[com], arg.strip() )
else:
logging.info("Ignored directive %s" %(com,))
else:
@@ -204,6 +206,37 @@ class GrubConfigFile(object):
if len(img) > 0:
self.add_image(GrubImage(img))
+ if self.hasPassword():
+ self.setPasswordAccess(False)
+
+ def hasPasswordAccess(self):
+ return self.passwordAccess
+
+ def setPasswordAccess(self, val):
+ self.passwordAccess = val
+
+ def hasPassword(self):
+ try:
+ getattr(self, self.commands['password'])
+ return True
+ except KeyError, e:
+ return False
+
+ def checkPassword(self, password):
+ try:
+ pwd = getattr(self, self.commands['password']).split()
+ if pwd[0] == '--md5':
+ import crypt
+ if crypt.crypt(password, pwd[1]) == pwd[1]:
+ return True
+
+ if pwd[0] == password:
+ return True
+
+ return False
+ except:
+ return True
+
def set(self, line):
(com, arg) = grub_exact_split(line, 2)
if self.commands.has_key(com):
diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub
index 93e157c4b7..f386e23036 100644
--- a/tools/pygrub/src/pygrub
+++ b/tools/pygrub/src/pygrub
@@ -418,7 +418,14 @@ class Grub:
self.text_win.addstr(0, 0, "Use the U and D keys to select which entry is highlighted.")
self.text_win.addstr(1, 0, "Press enter to boot the selected OS. 'e' to edit the")
self.text_win.addstr(2, 0, "commands before booting, 'a' to modify the kernel arguments ")
- self.text_win.addstr(3, 0, "before booting, or 'c' for a command line.")
+
+ # if grub has password defined we allow option to enter password
+ if not self.cf.hasPassword():
+ self.text_win.addstr(3, 0, "before booting, or 'c' for a command line.")
+ else:
+ self.text_win.addstr(3, 0, "before booting, or 'c' for a command line. You can also")
+ self.text_win.addstr(4, 0, "press 'p' to enter password for modifications...")
+
self.text_win.addch(0, 8, curses.ACS_UARROW)
self.text_win.addch(0, 14, curses.ACS_DARROW)
(y, x) = self.text_win.getmaxyx()
@@ -453,9 +460,19 @@ class Grub:
# handle keypresses
if c == ord('c'):
+ # we disallow access without password specified
+ if not self.cf.hasPasswordAccess():
+ self.text_win.addstr(6, 8, "You have to enter GRUB password first")
+ break
+
self.command_line_mode()
break
elif c == ord('a'):
+ # we disallow access without password specified
+ if not self.cf.hasPasswordAccess():
+ self.text_win.addstr(6, 8, "You have to enter GRUB password first")
+ break
+
# find the kernel line, edit it and then boot
img = self.cf.images[self.selected_image]
for line in img.lines:
@@ -467,9 +484,24 @@ class Grub:
break
break
elif c == ord('e'):
+ # we disallow access without password specified
+ if not self.cf.hasPasswordAccess():
+ self.text_win.addstr(6, 8, "You have to enter GRUB password first")
+ break
+
img = self.cf.images[self.selected_image]
self.edit_entry(img)
break
+ elif c == ord('p') and self.cf.hasPassword():
+ self.text_win.addstr(6, 8, "Enter password: ")
+ pwd = self.text_win.getstr(6, 8)
+ if not self.cf.checkPassword(pwd):
+ self.text_win.addstr(6, 8, "Incorrect password!")
+ self.cf.setPasswordAccess( False )
+ else:
+ self.text_win.addstr(6, 8, "Access granted ")
+ self.cf.setPasswordAccess( True )
+ break
elif c in (curses.KEY_ENTER, ord('\n'), ord('\r')):
self.isdone = True
break