예제 #1
0
    def import_data(self, input, password):
        "Imports data from a data stream to an entrystore"

        plaintext = decrypt(input, password, "GNOME Password Manager\n")

        entrystore = data.EntryStore()
        lines = plaintext.splitlines()

        while len(lines) > 0:

            e = entry.GenericEntry()

            e.name = lines[0]
            e[entry.UsernameField] = lines[1]
            e[entry.PasswordField] = lines[2]
            e[entry.HostnameField] = lines[3]
            e.updated = int(lines[5])
            desclen = int(lines[7])

            if e[entry.HostnameField] == "http://":
                e[entry.HostnameField] = ""

            del lines[:8]

            d = ""
            while len(d) < desclen and len(lines) > 0:
                d += lines[0] + "\n"
                del lines[0]

            e.description = re.sub("[\r\n]+", " ", d).strip()

            entrystore.add_entry(e)

        return entrystore
예제 #2
0
    def import_data(self, input, password):
        " Import data from a file into the entry store"

        entrystore = data.EntryStore()

        # Maintain a hash of folder names to folder entries so we
        # can use each category encountered to create a new folder
        # by that name, or use an existing one if we've already
        # created it:
        folders = {}

        for line in input.splitlines()[1:]:
            f_csv = csv.reader([line.decode()])
            for row in f_csv:

                # Raise FormatError if we don't have all 9 fields
                # KeepasXC 2.5 to 2.6.1 has 6 fields
                # KeepasXC 2.6.2 has 10 fields
                if len(row) != 6 and len(row) != 10:
                    raise base.FormatError

                # If URL is present create WebEntry
                if row[4]:
                    new_entry = entry.WebEntry()
                    new_entry[entry.URLField] = row[4]
                else:
                    new_entry = entry.GenericEntry()

                new_entry.name = row[1]
                new_entry[entry.UsernameField] = row[2]
                new_entry[entry.PasswordField] = row[3]
                new_entry.notes = row[5]

                # TODO As Last modified and creationtime are from newer
                # keepassXC releases, set to current time for now
                new_entry.updated = time.time()

                # Create and/or add to folder
                # TODO split folder name and correctly group them
                if row[0] in folders:
                    parent = folders[row[0]]

                else:
                    folder = entry.FolderEntry()
                    folder.name = row[0]
                    parent = entrystore.add_entry(folder)
                    folders[row[0]] = parent

                # Add the entry
                entrystore.add_entry(new_entry, parent)

        return entrystore
예제 #3
0
    def import_data(self, input, password):
        " Import data from a file into the entry store"

        # Replace any vertical tabs with spaces, SplashID seems to use
        # these to seperate lines within a Notes field:
        if input.count(b'\x0b'):
            input = input.replace(b'\x0b', b' ')

        entrystore = data.EntryStore()

        # Maintain a hash of folder names to folder entries so we
        # can use each category encountered to create a new folder
        # by that name, or use an existing one if we've already
        # created it:
        folders = {}

        for line in input.splitlines():
            for row in csv.reader([line.decode()]):

                # Raise FormatError if we don't have all 9 fields
                if len(row) != 9:
                    raise base.FormatError

                # Import the entry
                e = entry.GenericEntry()
                e.name = row[1]
                e.description = " / ".join(
                    [desc.strip() for desc in row[5:8] if desc.strip() != ""])
                e.updated = time.time()

                e[entry.UsernameField] = row[2]
                e[entry.PasswordField] = row[3]
                e[entry.HostnameField] = row[4]

                # Create and/or add to folder based on category:
                if row[8] in folders:
                    parent = folders[category]

                else:
                    folder = entry.FolderEntry()
                    folder.name = category
                    parent = entrystore.add_entry(new_folder)
                    folders[row[8]] = parent

                # Add the entry
                entrystore.add_entry(e, parent)

        return entrystore
예제 #4
0
 def __init__(self, passwords, filename, handler):
     cmd.Cmd.__init__(self)
     self.passwords = passwords
     self.filename = filename
     self.handler = handler
     self.data = data.EntryStore()
     self.intro = 'See `help` for a list of the command available.'
     self.path = "/"
     self.modified = False
     self.itera = self.passwords.get_iter_first()
     self.root_itera = self.passwords.get_iter_first()
     self.data.import_entry(self.passwords, self.root_itera)
     self.entrysearch = data.EntrySearch(self.passwords)
     if not TKIMPORT:
         warn('The copy command from the interactive shell will not be available. '\
     'Install the Tkinter library to have it.')
예제 #5
0
	def __init__(self, entries):
		dialog.Popup.__init__(self)
		self.set_default_size(225, 200)

		self.entrystore = data.EntryStore()
		self.entrystore.set_sort_column_id(0, gtk.SORT_ASCENDING)

		for e in entries:
			self.entrystore.add_entry(e)

		self.treeview = ui.EntryTree(self.entrystore)
		self.treeview.set_cursor((0,))
		self.treeview.connect("row-activated", self.__cb_row_activated)

		self.scrolledwindow = ui.ScrolledWindow(self.treeview)
		self.scrolledwindow.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
		self.add(self.scrolledwindow)
예제 #6
0
	def __init_facilities(self):
		"Sets up facilities"

		self.clipboard		= data.Clipboard()
		self.datafile		= io.DataFile(datahandler.Revelation2)
		self.entrystore		= data.EntryStore()
		self.entrysearch	= data.EntrySearch(self.entrystore)
		self.items		= ui.ItemFactory(self.applet)
		self.locktimer		= data.Timer()

		self.config.monitor("autolock_timeout", lambda k,v,d: self.locktimer.start(v * 60))
		self.config.monitor("file", self.__cb_config_file)

		self.datafile.connect("changed", self.__cb_file_changed)
		self.datafile.connect("content-changed", self.__cb_file_content_changed)
		self.locktimer.connect("ring", self.__cb_file_autolock)

		self.entrysearch.folders = False
예제 #7
0
    def import_data(self, input, password):
        "Imports data into an entrystore"

        # read header and test password
        if password is None:
            raise base.PasswordError

        random = input[0:8]
        testhash = input[8:28]
        salt = input[28:48]
        iv = input[48:56]

        if testhash != generate_testhash(password, random):
            raise base.PasswordError

        # load data
        db = decrypt(SHA(password.encode() + salt).digest(), input[56:], iv)
        entrystore = data.EntryStore()

        while len(db) > 0:

            dbentry = {"name": "", "username": "", "password": "", "note": ""}

            for f in ("name", "password", "note"):
                flen, ftype = parse_field_header(db[:8])
                value = db[8:8 + flen]

                if f == "name" and b"\xAD" in value:
                    value, dbentry["username"] = value.split(b"\xAD", 1)

                dbentry[f] = value
                db = db[8 + flen:]

            e = entry.GenericEntry()
            e.name = normalize_field(dbentry["name"])
            e.description = normalize_field(dbentry["note"])
            e[entry.UsernameField] = normalize_field(dbentry["username"])
            e[entry.PasswordField] = normalize_field(dbentry["password"])

            entrystore.add_entry(e)

        return entrystore
예제 #8
0
    def import_data(self, input, password=None):
        "Imports data from a data stream to an entrystore"

        RevelationXML.check(self, input)

        try:
            dom = xml.dom.minidom.parseString(input.strip())

        except ExpatError:
            raise base.FormatError

        if dom.documentElement.nodeName != "revelationdata":
            raise base.FormatError

        if not dom.documentElement.attributes.has_key("dataversion"):
            raise base.FormatError

        entrystore = data.EntryStore()

        for node in dom.documentElement.childNodes:
            self.__xml_import_node(entrystore, node)

        return entrystore
예제 #9
0
    def import_data(self, input, password):
        "Imports data from a data stream to an entrystore"

        plaintext = decrypt(input, password, "GPassFile version 1.1.0")

        entrystore = data.EntryStore()
        foldermap = {}

        while len(plaintext) > 0:

            # parse data
            id = self.__getint(plaintext[:4])
            plaintext = plaintext[4:]

            parentid = self.__getint(plaintext[:4])
            plaintext = plaintext[4:]

            entrytype = self.__getstr(plaintext)
            plaintext = plaintext[4 + len(entrytype):]

            attrdata = self.__getstr(plaintext)
            plaintext = plaintext[4 + len(attrdata):]

            l, name = self.__unpackstr(attrdata)
            attrdata = attrdata[l:]

            l, desc = self.__unpackstr(attrdata)
            attrdata = attrdata[l:]

            l, ctime = self.__unpackint(attrdata)
            attrdata = attrdata[l:]

            l, mtime = self.__unpackint(attrdata)
            attrdata = attrdata[l:]

            l, expire = self.__unpackint(attrdata)
            attrdata = attrdata[l:]

            l, etime = self.__unpackint(attrdata)
            attrdata = attrdata[l:]

            if entrytype == "general":
                l, username = self.__unpackstr(attrdata)
                attrdata = attrdata[l:]

                l, password = self.__unpackstr(attrdata)
                attrdata = attrdata[l:]

                l, hostname = self.__unpackstr(attrdata)
                attrdata = attrdata[l:]

            else:
                username = password = hostname = ""

            # create entry
            if entrytype == "general":
                e = entry.GenericEntry()

                e.name = self.__normstr(name)
                e.description = self.__normstr(desc)
                e.updated = mtime

                e[entry.HostnameField] = self.__normstr(hostname)
                e[entry.UsernameField] = self.__normstr(username)
                e[entry.PasswordField] = self.__normstr(password)

            elif entrytype == "folder":
                e = entry.FolderEntry()

                e.name = self.__normstr(name)
                e.description = self.__normstr(desc)
                e.updated = mtime

            else:
                continue

            # add entry to entrystore
            if foldermap.has_key(parentid):
                parent = foldermap[parentid]

            else:
                parent = None

            iter = entrystore.add_entry(e, parent)

            if type(e) == entry.FolderEntry:
                foldermap[id] = iter

        return entrystore
예제 #10
0
    def import_data(self, input, password):
        "Imports data into an entrystore"

        # read header and test password
        if password is None:
            raise base.PasswordError

        random = input[0:8]
        testhash = input[8:28]
        salt = input[28:48]
        iv = input[48:56]

        if testhash != generate_testhash(password, random):
            raise base.PasswordError

        # load data
        db = decrypt(SHA(password.encode() + salt).digest(), input[56:], iv)
        entrystore = data.EntryStore()

        # read magic entry
        for f in "magic", "version", "prefs":
            flen, ftype = parse_field_header(db)
            value = db[8:8 + flen]

            if f == "magic" and value != b" !!!Version 2 File Format!!! Please upgrade to PasswordSafe 2.0 or later":
                raise base.FormatError

            db = db[8 + flen:]

        # import entries
        e = entry.GenericEntry()
        group = None
        groupmap = {}

        while len(db) > 0:
            flen, ftype = parse_field_header(db)
            value = normalize_field(db[8:8 + flen])

            if ftype == FIELDTYPE_NAME:
                if b"\xAD" not in value:
                    e.name = value

                else:
                    n, u = value.split(b"\xAD", 1)

                    e.name = normalize_field(n)
                    e[entry.UsernameField] = normalize_field(u)

            elif ftype == FIELDTYPE_TITLE:
                e.name = value

            elif ftype == FIELDTYPE_USER:
                e[entry.UsernameField] = value

            elif ftype == FIELDTYPE_PASSWORD:
                e[entry.PasswordField] = value

            elif ftype == FIELDTYPE_NOTES:
                e.description = value

            elif ftype == FIELDTYPE_UUID:
                pass

            elif ftype == FIELDTYPE_GROUP:
                group = value

            elif ftype == FIELDTYPE_END:
                if group not in (None, ""):
                    parent = self.__setup_group(entrystore, groupmap, group)

                else:
                    parent = None

                entrystore.add_entry(e, parent)

                e = entry.GenericEntry()
                group = None

            else:
                pass

            db = db[8 + flen:]

        return entrystore
예제 #11
0
	def import_data(self, input, password):
		"Imports data into an entrystore"

		try:

			# check and load data
			self.check(input)
			dom = xml.dom.minidom.parseString(input.strip())

			if dom.documentElement.nodeName != "FPM":
				raise base.FormatError


			# set up decryption engine, and check if password is correct
			keynode = dom.documentElement.getElementsByTagName("KeyInfo")[0]
			salt = keynode.attributes["salt"].nodeValue
			vstring = keynode.attributes["vstring"].nodeValue

			password = MD5.new(salt + password).digest()
			cipher = Blowfish.new(password)

			if self.__decrypt(cipher, vstring) != "FIGARO":
				raise base.PasswordError

		except ExpatError:
			raise base.FormatError


		except ( IndexError, KeyError ):
			raise base.FormatError


		# import entries into entrystore
		entrystore = data.EntryStore()
		folders = {}

		for node in dom.getElementsByTagName("PasswordItem"):

			parent = None
			e = entry.GenericEntry()

			for fieldnode in [ node for node in node.childNodes if node.nodeType == node.ELEMENT_NODE ]:

				content = self.__decrypt(cipher, util.dom_text(fieldnode))

				if content == "":
					continue

				elif fieldnode.nodeName == "title":
					e.name = content

				elif fieldnode.nodeName == "user":
					e.get_field(entry.UsernameField).value = content

				elif fieldnode.nodeName == "url":
					e.get_field(entry.HostnameField).value = content

				elif fieldnode.nodeName == "password":
					e.get_field(entry.PasswordField).value = content
	
				elif fieldnode.nodeName == "notes":
					e.description = content

				elif fieldnode.nodeName == "category":

					if content in folders:
						parent = folders[content]

					else:
						folderentry = entry.FolderEntry()
						folderentry.name = content

						parent = entrystore.add_entry(folderentry)
						folders[content] = parent

			entrystore.add_entry(e, parent)

		return entrystore
예제 #12
0
    def import_data(self, netrc, password = None):
        "Imports data from a netrc stream to an entrystore"

        entrystore = data.EntryStore()

        # set up a lexical parser
        datafp = StringIO(netrc)
        lexer = shlex.shlex(datafp)
        lexer.wordchars += r"!\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"

        while True:
            # look for a machine, default or macdef top-level keyword
            tt = lexer.get_token()

            if not tt:
                break

            elif tt == "machine":
                name = lexer.get_token()

            elif tt == "default":
                name = "default"

            # skip macdef entries
            elif tt == "macdef":
                lexer.whitespace = ' \t'

                while True:
                    line = lexer.instream.readline()

                    if not line or line == '\012':
                        lexer.whitespace = ' \t\r\n'
                        break
                continue

            else:
                raise base.FormatError

            # we're looking at an entry, so fetch data
            e = entry.GenericEntry()
            e.name = name
            e.updated = time.time()

            if name != "default":
                e[entry.HostnameField] = name

            while True:
                tt = lexer.get_token()

                # if we find a new entry, break out of current field-collecting loop
                if tt == "" or tt == "machine" or tt == "default" or tt == "macdef":
                    entrystore.add_entry(e)
                    lexer.push_token(tt)
                    break

                elif tt == "login" or tt == "user":
                    e[entry.UsernameField] = lexer.get_token()

                elif tt == "account":
                    lexer.get_token()

                elif tt == "password":
                    e[entry.PasswordField] = lexer.get_token()

                else:
                    raise base.FormatError

        datafp.close()

        return entrystore