By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,676 Members | 2,249 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,676 IT Pros & Developers. It's quick & easy.

write md5 to file

P: 4
I am trying to get StartUp-Manager to write the grub password in encrypted form to menu.lst. Currently it writes the password in plain-text and that is not too clever...

This is the function I currently use:
Expand|Select|Wrap|Line Numbers
  1. def on_update_password_button_clicked(self, widget):
  2.         if self.password_entry.get_text() == self.confirm_password_entry.get_text():
  3.                 password=self.password_entry.get_text()
  4.                 if self.password_protect_check.get_active():
  5.                         change_config("password", None, "password "+password+"\n")
  6.                 else:
  7.                         change_config("password", None, "#password "+password+"\n")
  8. ...snip
And here is the "change_config" function:
Expand|Select|Wrap|Line Numbers
  1. def change_config(identifier, old_value, new_value):
  2.         """Changes the configuration file based on the passed values."""
  3.         line_number=get_line_number(identifier)
  4.         lines=get_lines_of_file(Config.menu)
  5.         line=lines[line_number]
  6.         if old_value == None:
  7.                 lines[line_number]=new_value
  8.         elif old_value == "vga=":
  9.                 place=line.find(old_value)
  10.         if place != -1:
  11.                         line=line[:place]+new_value+line[place+7:]
  12.                 else:
  13.                         place=line.find("\n")
  14.                         line=line[:-1]+" "+new_value+"\n"
  15.                 lines[line_number]=line
  16.         else:
  17.                 if old_value[0] != "#" and line.find(" "+old_value) != -1:
  18.                         old_value=" "+old_value
  19.  
  20.                 if old_value[0] == "#" and line.find("# "+old_value[1:]) != -1:
  21.                         old_value="# "+old_value[1:]
  22.  
  23.                 line=line.replace(old_value, new_value)
  24.                 lines[line_number]=line
  25.  
  26.         output_file=open(Config.menu, 'w')
  27.         for out_line in lines:
  28.                 output_file.write(out_line)
  29.         output_file.close()
I have tried this:

Expand|Select|Wrap|Line Numbers
  1. snip...
  2.  
  3. import md5
  4. password=md5.new(password).digest()
  5. change_config("password", None, "password --md5 "+password+"\n")
  6.  
  7. ...snip
Which would corrupt the textfile.

This:
Expand|Select|Wrap|Line Numbers
  1. snip...
  2.  
  3. import md5
  4. password=md5.new(password).hexdigest()
  5. change_config("password", None, "password --md5 "+password+"\n")
  6.  
  7. ...snip
Which does not nuke the textfile, but grub (the bootloader reading the textfile) does not recognise the encrypted password.

So now I am thinking about using the grub-md5-crypt(it is the program recommended for creating this md5).
Instead of using my change_config function, do something like this:

Expand|Select|Wrap|Line Numbers
  1. os.system('grub-md5-crypt | some cool sed thing')
Now the problem is that I have no clue how to pass the password to grub-md5-crypt as it is interactive. Observe:
Expand|Select|Wrap|Line Numbers
  1. jimmy@ubuntu:~$ grub-md5-crypt 
  2. Password: 
  3. Retype password: 
  4. $1$nWkej1$2zfBZK52J4hSlxI5x5EV/0
And from the man page for grub-md5-crypt
Expand|Select|Wrap|Line Numbers
  1. DESCRIPTION
  2.        Encrypt a password in MD5 format.
  3.  
  4.        -h, --help
  5.               print this message and exit
  6.  
  7.        -v, --version
  8.               print the version information and exit
  9.  
  10.        --grub-shell=FILE
  11.               use FILE as the grub shell
  12.  
it does not seem like it is possible to send the password as an argument.

I feel stuck here. Any help is appreciated.
Nov 30 '06 #1
Share this Question
Share on Google+
7 Replies


P: 38
There is an Excpect implementation for Python called Pexpect. It can be used to interact with os calls.

http://pexpect.sourceforge.net/

But of course there has got to be a better way either to pass the password to the linux command or to use the md5 Python implementation.

Can you please publish a normal Grub password file and one generated from Python that Grub cannot read?

Best regards
/Fredrik
Nov 30 '06 #2

P: 4
Ok, here is the line in question:

Generated from python with .hexdigest()
password --md5 098f6bcd4621d373cade4e832627b4f6

Generated from python with .digest()
password --md5 �k�F!�s��N�&'��

Generated from grub-md5-crypt
password --md5 $1$Kxafj1$Hz4LuQNJ6UsGkadbkm9jE0
Nov 30 '06 #3

bartonc
Expert 5K+
P: 6,596
Usage I've seen looks like this:

Expand|Select|Wrap|Line Numbers
  1. import md5
  2. hexstring = md5.md5(data).hexdigest()
The link is here
Dec 1 '06 #4

P: 4
Thanks, but md5.md5() is an other name for md5.new()
md5.md5() is "For backward compatibility reasons"
http://docs.python.org/lib/module-md5.html
The module md5 is also deprecated, but that is another issue(my distro use python 2.4)

Anyway, I have investigated further.
I downloaded the grub source code and saw that grub-md5-crypt was only a shell-script wrapper around /sbin/grub itself.

So I reverse-engineered the code in grub-md5-crypt to make it accept command-line arguments:

Expand|Select|Wrap|Line Numbers
  1. #! /bin/sh
  2. password=$1
  3. /sbin/grub --batch --device-map=/dev/null <<EOF \
  4.     | grep "^Encrypted: " | sed 's/^Encrypted: //'
  5. md5crypt
  6. $password
  7. quit
  8. EOF
  9. exit 0
So my current solution is to do something like this in my python code:
Expand|Select|Wrap|Line Numbers
  1. os.system('./grub-md5-crypt-adapted password | some other command that changes menu.lst')
I will try it later, it will hopefully work...
Dec 1 '06 #5

bartonc
Expert 5K+
P: 6,596
Thanks, but md5.md5() is an other name for md5.new()
md5.md5() is "For backward compatibility reasons"
http://docs.python.org/lib/module-md5.html
The module md5 is also deprecated, but that is another issue(my distro use python 2.4)

Anyway, I have investigated further.
I downloaded the grub source code and saw that grub-md5-crypt was only a shell-script wrapper around /sbin/grub itself.

So I reverse-engineered the code in grub-md5-crypt to make it accept command-line arguments:

Expand|Select|Wrap|Line Numbers
  1. #! /bin/sh
  2. password=$1
  3. /sbin/grub --batch --device-map=/dev/null <<EOF \
  4.     | grep "^Encrypted: " | sed 's/^Encrypted: //'
  5. md5crypt
  6. $password
  7. quit
  8. EOF
  9. exit 0
So my current solution is to do something like this in my python code:
Expand|Select|Wrap|Line Numbers
  1. os.system('./grub-md5-crypt-adapted password | some other command that changes menu.lst')
I will try it later, it will hopefully work...
Thanks for the update. Keep posting (sorry we weren't of more help on this one),
Barton
Dec 1 '06 #6

P: 4
I am done :D
The solution was probably not the most elegant, but my approaching headache suggested that I should take the easy route :)

Here are the relevant parts of the main program:
Expand|Select|Wrap|Line Numbers
  1. snip...
  2. class Config:
  3. snip...
  4.         sum_md5='/usr/bin/startup-manager-md5.sh'
  5.         md5_file='/tmp/grub_password_line'
  6. snip...
  7. class SumGui:
  8. snip...
  9.     def on_update_password_button_clicked(self, widget):
  10.                 password=self.password_entry.get_text()
  11.                 if password == self.confirm_password_entry.get_text() and len(password) > 3:
  12.                         os.system(Config.sum_md5+' '+password)
  13.                         password=get_lines_of_file(Config.md5_file)
  14.                         if len(password) == 1 and password[0][:14] == "password --md5":
  15.                                 password=password[0]
  16.                         else:
  17.                                 self.password_notify_label.set_text(_('Error while changing passwords, md5 file corrupted')) #The _('') is used for translations
  18.                                 return 1
  19.  
  20.                         if not self.password_protect_check.get_active():
  21.                                 password="#"+password
  22.  
  23.                         change_config("password", None, password)
  24.                         self.password_notify_label.set_text(_('Password changed'))
  25.  
  26.                 else:
  27.                         if len(password) < 4:
  28.                                 self.password_notify_label.set_text(_('Password must be at least 4 characters'))
  29.                         else:
  30.                                 self.password_notify_label.set_text(_('Passwords do not match'))
  31.  
And the startup-manager-md5.sh that I made:
Expand|Select|Wrap|Line Numbers
  1. #! /bin/sh
  2. password=$1
  3. /sbin/grub --batch --device-map=/dev/null <<EOF \
  4.     | grep "^Encrypted: " | sed -n 's/^Encrypted: /password --md5 /w /tmp/grub_password_line'
  5. md5crypt
  6. $password
  7. quit
  8. EOF
  9. exit 0
In short: Get password from the gui, check so it is valid, send it to startup-manager-md5.sh which writes it in encrypted form to a file in /tmp.
Read file from /tmp, check so it is valid and then use the change_config() function to write it to menu.lst.

As I said, not the most elegant solution, but it works :)
Dec 1 '06 #7

bartonc
Expert 5K+
P: 6,596
Looks good, and it works. Thanks for the update.
Dec 1 '06 #8

Post your reply

Sign in to post your reply or Sign up for a free account.