write md5 to file

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • nonameisfree
    New Member
    • Nov 2006
    • 4

    #1

    write md5 to file

    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:
    Code:
    def on_update_password_button_clicked(self, widget):
            if self.password_entry.get_text() == self.confirm_password_entry.get_text():
                    password=self.password_entry.get_text()
                    if self.password_protect_check.get_active():
                            change_config("password", None, "password "+password+"\n")
                    else:
                            change_config("password", None, "#password "+password+"\n")
    ...snip
    And here is the "change_con fig" function:
    Code:
    def change_config(identifier, old_value, new_value):
            """Changes the configuration file based on the passed values."""
            line_number=get_line_number(identifier)
            lines=get_lines_of_file(Config.menu)
            line=lines[line_number]
            if old_value == None:
                    lines[line_number]=new_value
            elif old_value == "vga=":
                    place=line.find(old_value)
    		if place != -1:
                            line=line[:place]+new_value+line[place+7:]
                    else:
                            place=line.find("\n")
                            line=line[:-1]+" "+new_value+"\n"
                    lines[line_number]=line
            else:
                    if old_value[0] != "#" and line.find(" "+old_value) != -1:
                            old_value=" "+old_value
    
                    if old_value[0] == "#" and line.find("# "+old_value[1:]) != -1:
                            old_value="# "+old_value[1:]
    
                    line=line.replace(old_value, new_value)
                    lines[line_number]=line
    
            output_file=open(Config.menu, 'w')
            for out_line in lines:
                    output_file.write(out_line)
            output_file.close()
    I have tried this:

    Code:
    snip...
    
    import md5
    password=md5.new(password).digest()
    change_config("password", None, "password --md5 "+password+"\n")
    
    ...snip
    Which would corrupt the textfile.

    This:
    Code:
    snip...
    
    import md5
    password=md5.new(password).hexdigest()
    change_config("password", None, "password --md5 "+password+"\n")
    
    ...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:

    Code:
    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:
    Code:
    jimmy@ubuntu:~$ grub-md5-crypt 
    Password: 
    Retype password: 
    $1$nWkej1$2zfBZK52J4hSlxI5x5EV/0
    And from the man page for grub-md5-crypt
    Code:
    DESCRIPTION
           Encrypt a password in MD5 format.
    
           -h, --help
                  print this message and exit
    
           -v, --version
                  print the version information and exit
    
           --grub-shell=FILE
                  use FILE as the grub shell
    it does not seem like it is possible to send the password as an argument.

    I feel stuck here. Any help is appreciated.
  • fuffens
    New Member
    • Oct 2006
    • 38

    #2
    There is an Excpect implementation for Python called Pexpect. It can be used to interact with os calls.

    Download Pexpect - Pure Python Expect-like module for free. Pexpect is a Python module for spawning child applications; controlling them;


    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

    Comment

    • nonameisfree
      New Member
      • Nov 2006
      • 4

      #3
      Ok, here is the line in question:

      Generated from python with .hexdigest()
      password --md5 098f6bcd4621d37 3cade4e832627b4 f6

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

      Generated from grub-md5-crypt
      password --md5 $1$Kxafj1$Hz4Lu QNJ6UsGkadbkm9j E0

      Comment

      • bartonc
        Recognized Expert Expert
        • Sep 2006
        • 6478

        #4
        Usage I've seen looks like this:

        Code:
        import md5
        hexstring = md5.md5(data).hexdigest()
        The link is here

        Comment

        • nonameisfree
          New Member
          • Nov 2006
          • 4

          #5
          Thanks, but md5.md5() is an other name for md5.new()
          md5.md5() is "For backward compatibility reasons"

          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:

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

          Comment

          • bartonc
            Recognized Expert Expert
            • Sep 2006
            • 6478

            #6
            Originally posted by nonameisfree
            Thanks, but md5.md5() is an other name for md5.new()
            md5.md5() is "For backward compatibility reasons"

            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:

            Code:
            #! /bin/sh
            password=$1
            /sbin/grub --batch --device-map=/dev/null <<EOF \
                | grep "^Encrypted: " | sed 's/^Encrypted: //'
            md5crypt
            $password
            quit
            EOF
            exit 0
            So my current solution is to do something like this in my python code:
            Code:
            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

            Comment

            • nonameisfree
              New Member
              • Nov 2006
              • 4

              #7
              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:
              Code:
              snip...
              class Config:
              snip...
                      sum_md5='/usr/bin/startup-manager-md5.sh'
                      md5_file='/tmp/grub_password_line'
              snip...
              class SumGui:
              snip...
                  def on_update_password_button_clicked(self, widget):
                              password=self.password_entry.get_text()
                              if password == self.confirm_password_entry.get_text() and len(password) > 3:
                                      os.system(Config.sum_md5+' '+password)
                                      password=get_lines_of_file(Config.md5_file)
                                      if len(password) == 1 and password[0][:14] == "password --md5":
                                              password=password[0]
                                      else:
                                              self.password_notify_label.set_text(_('Error while changing passwords, md5 file corrupted')) #The _('') is used for translations
                                              return 1
              
                                      if not self.password_protect_check.get_active():
                                              password="#"+password
              
                                      change_config("password", None, password)
                                      self.password_notify_label.set_text(_('Password changed'))
              
                              else:
                                      if len(password) < 4:
                                              self.password_notify_label.set_text(_('Password must be at least 4 characters'))
                                      else:
                                              self.password_notify_label.set_text(_('Passwords do not match'))
              And the startup-manager-md5.sh that I made:
              Code:
              #! /bin/sh
              password=$1
              /sbin/grub --batch --device-map=/dev/null <<EOF \
                  | grep "^Encrypted: " | sed -n 's/^Encrypted: /password --md5 /w /tmp/grub_password_line'
              md5crypt
              $password
              quit
              EOF
              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 :)

              Comment

              • bartonc
                Recognized Expert Expert
                • Sep 2006
                • 6478

                #8
                Looks good, and it works. Thanks for the update.

                Comment

                Working...