import re
import sys
import string
import printer
from collections import namedtuple
from binascii import *
from sandutils import *
import os
import subprocess
from modules.sandmountddfromkey.sandmountddfromkey import *

class SandMountDDFromPwd(SandMountDDFromKey):


   def __init__(self, printer, project):
      self.printer=printer
      self.project=project
      self.params={
		  "out_dir":{"description":"Where to generate the results and download files on the computer.",
			      "value":"results",
			      "required":True
			      },
		  "image_file":{"description":"The dd image of the encrypted phone.",
			      "value":"%s_data.dd" % self.project,
			      "required":True
			      },
		  "password":{"description":"Password or pin to decrypt the phone",
			      "value":"qwertz2",
			      "required":True
			      },
		   "mnt_dest":{"description":"Where to mount.",
			      "value":"/mnt/userdata",
			      "required":True
			      },
		  }
      self.setparams(self.params)

   def setparams(self, params):
      self.params=params
      self.out_dir = self.params["out_dir"]["value"]
      self.password = self.params["password"]["value"]
      self.image_file = self.params["image_file"]["value"]
      self.mnt_dest = self.params["mnt_dest"]["value"]

   def getparams(self):
      return self.params

   def get_footer_from_dd(self):

      '''
      Extract the DEK from dd. If it is S4 tries to open project_footer file,
      generated by the sands4getdek.
      '''

      keypaddingsalt=""
      self.printer.print_debug("Open the dd image file: %s/%s" % (self.out_dir, self.image_file))
      try:
	 f=open("%s/%s" % (self.out_dir, self.image_file),"rb")
	 try:
	    f.seek(-0x4000, os.SEEK_END)
	    f.seek(0x84,1)
	    keypaddingsalt=f.read(80)
	 finally:
	    f.close()
      except IOError as e:
	 self.printer.print_err("I/O error({0}): {1} {2}/{3}".format(e.errno, e.strerror, self.out_dir, self.image_file))
	 return ""
      
      if(keypaddingsalt[0:5]=="\0\0\0\0\0"):
	 self.printer.print_info("The first five bytes are zero, assuming it is S4.")
	 self.printer.print_debug("Open the footer file: %s/%s_footer" % (self.out_dir, self.project))
	 try:
	    f=open("%s/%s_footer" % (self.out_dir, self.project),"rb")
	    try:
	       f.seek(0x84)
	       keypaddingsalt=f.read(80)
	    finally:
	       f.close()
	 except IOError as e:
	    self.printer.print_err("I/O error({0}): {1} {2}/{3}_footer".format(e.errno, e.strerror, self.out_dir, self.project))
	    return ""
      
      return keypaddingsalt
     

   def mountddfrompwd(self, image_file, password, mnt_dest):
      keypaddingsalt=self.get_footer_from_dd()
      if(keypaddingsalt==""):
	 self.printer.print_err("Could not mount dd image: %s/%s" % (self.out_dir, self.image_file))
	 return -1
      binkey,mkey = decrypt_key(keypaddingsalt[:32], keypaddingsalt[64:], password)
      padding=create_padding(keypaddingsalt[:32], mkey)
      if(padding!=keypaddingsalt[32:64]):
	 self.printer.print_err("The given password is wrong!")
	 self.printer.print_err("Could not mount dd image: %s/%s" % (self.out_dir, self.image_file))
	 return -1
      
      try:
	 f=open("%s/%s_dek_formount" % (self.out_dir, self.project),"wb")
	 try:
	       f.write(binkey)
	 finally:
	    f.close()
      except IOError as e:
	 self.printer.print_err("I/O error({0}): {1} {2}/{3}_footer".format(e.errno, e.strerror, self.out_dir, self.project))
	 return -1
      
      return self.mountddfromkey("%s/%s" % (self.out_dir, self.image_file), "%s/%s_dek_formount" % (self.out_dir, self.project), self.mnt_dest)
      

  
   def do(self):
      return self.mountddfrompwd("%s/%s" % (self.out_dir, self.image_file), self.password, self.mnt_dest)
    
