예제 #1
0
def check_string(xml_data):
    if not _find_in_path('gpg'):
        raise SafeException(
            "GnuPG is not installed ('gpg' not in $PATH). See http://gnupg.org"
        )

    if xml_data.startswith("<?xml "):
        return _check_xml_string(xml_data)

    raise SafeException("Data is not a valid xml document")
예제 #2
0
def import_key(stream):
    """Run C{gpg --import} with this stream as stdin."""
    errors = tempfile.TemporaryFile()

    child = os.fork()
    if child == 0:
        # We are the child
        try:
            try:
                os.dup2(stream.fileno(), 0)
                os.dup2(errors.fileno(), 2)
                os.execlp('gpg', 'gpg', '--no-secmem-warning', '--quiet',
                          '--import')
            except:
                traceback.print_exc()
        finally:
            os._exit(1)
        assert False

    pid, status = os.waitpid(child, 0)
    assert pid == child

    errors.seek(0)
    error_messages = errors.read().strip()
    errors.close()

    if error_messages:
        raise SafeException("Errors from 'gpg --import':\n%s" % error_messages)
예제 #3
0
파일: recipe.py 프로젝트: probonopd/klik
	def load_from_string(self, xml):
		try:
			self.original_xml = xml
			document = parseString(xml)

		except Exception, e:
			raise SafeException("Error recipe could not be loaded does not appear to be valid XML (%s)" % e)
예제 #4
0
파일: recipe.py 프로젝트: probonopd/klik
	def load_from_file(self, path):
		try:
			f = open(path, "r")
			xml = f.read()
			f.close()
			self.load_from_string(xml)
		except Exception, e:
			raise SafeException("Error recipe could not be loaded does not appear to be valid XML (%s)" % e)
예제 #5
0
def _get_sigs_from_gpg_status_stream(status_r, child, errors):
    """Read messages from status_r and collect signatures from it.
	When done, reap 'child'.
	If there are no signatures, throw SafeException (using errors
	for the error message if non-empty)."""
    sigs = []

    # Should we error out on bad signatures, even if there's a good
    # signature too?

    for line in os.fdopen(status_r):
        assert line.endswith('\n')
        assert line.startswith('[GNUPG:] ')
        line = line[9:-1]
        split_line = line.split(' ')
        code = split_line[0]
        args = split_line[1:]
        if code == 'VALIDSIG':
            sigs.append(ValidSig(args))
        elif code == 'BADSIG':
            sigs.append(BadSig(args))
        elif code == 'ERRSIG':
            sigs.append(ErrSig(args))

    pid, status = os.waitpid(child, 0)
    assert pid == child

    errors.seek(0)

    error_messages = errors.read().strip()
    errors.close()

    if not sigs:
        if error_messages:
            raise SafeException("No signatures found. Errors from GPG:\n%s" %
                                error_messages)
        else:
            raise SafeException(
                "No signatures found. No error messages from GPG.")

    return sigs
예제 #6
0
파일: base.py 프로젝트: probonopd/klik
    def get_recipe(self, application_name):

        # Get information about users system
        plat = platform.system() + " " + platform.machine()
        pyvers = "Python/" + platform.python_version()

        useragent = "klik/%s (%s; %s; %s; %s;) %s (%s)" % (
            self.settings.version, self.xdg.get_is_terminal(), plat,
            self.xdg.get_lang(), self.xdg.get_desktop_enviroment() + "+" +
            "+".join(self.xdg.get_installed_libs()), pyvers,
            self.xdg.get_distribution())

        # Convert to lower case for comparing
        application_name = application_name.lower()

        # Download Recipe
        if application_name.startswith("http://"):
            url = application_name
        else:
            # Strip klik protocol
            if application_name.startswith("klik2://"):
                application_name = application_name[8:]
            elif application_name.startswith("klik2:"):
                application_name = application_name[6:]

            if application_name.startswith("klik://"):
                application_name = application_name[7:]
            elif application_name.startswith("klik:"):
                application_name = application_name[5:]

            url = self.settings.default_download_url + application_name

        print "Recipe URL: " + url
        try:
            request = urllib2.Request(url)
            request.add_header('User-Agent', useragent)
            opener = urllib2.build_opener()
            data = opener.open(request).read()
        except:
            raise SafeException(
                "Error occurred while attempting to download recipe")

        # Load Recipe
        print ""
        print "Parsing recipe..."
        recipe = KlikRecipe()
        recipe.load_from_string(data)
        self.print_recipe(recipe)

        return recipe
예제 #7
0
def _check_xml_string(data_to_check):

    xml_comment_start = '<!-- Base64 Signature'

    last_comment = data_to_check.rfind('\n' + xml_comment_start)
    if last_comment < 0:
        raise SafeException(
            "No signature block in XML. Maybe this file isn't signed?")
    last_comment += 1  # Include new-line in data

    data = tempfile.TemporaryFile()

    # Killerkiwi 2007-09-12 - Added rstrip to remove trailing spaces that invalidates signing
    data.write(data_to_check[:last_comment].rstrip())
    data.flush()
    os.lseek(data.fileno(), 0, 0)

    errors = tempfile.TemporaryFile()

    sig_lines = data_to_check[last_comment:].split('\n')
    if sig_lines[0].strip() != xml_comment_start:
        raise SafeException('Bad signature block: extra data on comment line')
    while sig_lines and not sig_lines[-1].strip():
        del sig_lines[-1]
    if sig_lines[-1].strip() != '-->':
        raise SafeException(
            'Bad signature block: last line is not end-of-comment')
    sig_data = '\n'.join(sig_lines[1:-1])

    if re.match('^[ A-Za-z0-9+/=\n]+$', sig_data) is None:
        raise SafeException(
            "Invalid characters found in base 64 encoded signature")
    try:
        sig_data = base64.decodestring(sig_data)  # (b64decode is Python 2.4)
    except Exception, ex:
        raise SafeException("Invalid base 64 encoded signature: " + str(ex))
예제 #8
0
def check_stream(stream):
    """Pass stream through gpg --decrypt to get the data, the error text,
	and a list of signatures (good or bad). If stream starts with "<?xml "
	then get the signature from a comment at the end instead (and the returned
	data is the original stream). stream must be seekable.
	@note: Stream returned may or may not be the one passed in. Be careful!
	@return: (data_stream, [Signatures])"""
    if not _find_in_path('gpg'):
        raise SafeException(
            "GnuPG is not installed ('gpg' not in $PATH). See http://gnupg.org"
        )

    #stream.seek(0)
    #all = stream.read()
    stream.seek(0)

    start = stream.read(6)
    stream.seek(0)
    if start == "<?xml ":
        return _check_xml_stream(stream)
    else:
        os.lseek(stream.fileno(), 0, 0)
        return _check_plain_stream(stream)
예제 #9
0
    def __load_from_document(self, document):

        interface = self.__getFirstNode(document, "interface")
        error = self.__getFirstNode(document, "error")

        if interface != None:
            self.source_uri = interface.getAttribute("uri")

            name = self.__getFirstNode(interface, "name")

            if name != None and name.firstChild != None:
                self.name = self.__getNodeValue(name, "")

                # default command is app name
                self.command = self.name

                description = self.__getFirstNode(interface, "description")
                if description != None:
                    self.description = self.__getNodeValue(description, "")

                summary = self.__getFirstNode(interface, "summary")
                if summary != None:
                    self.summary = self.__getNodeValue(summary, "")

                icon = self.__getFirstNode(interface, "icon")
                if icon != None:
                    self.icon = icon.getAttribute("href")

                debtags = self.__getFirstNode(interface, "debtags")
                if debtags != None:
                    nodes = interface.getElementsByTagName("tag")

                    if len(nodes) > 0:
                        self.require_terminal = False
                    for node in nodes:
                        value = self.__getNodeValue(node, None)
                        if value != None:
                            if value == "interface::commandline":
                                self.require_terminal = True
                            value = value.split("::")
                            self.debtags[value[0]] = value[1]

                group = self.__getFirstNode(interface, "group")
                if group != None:
                    if group.attributes["main"] != None:
                        self.command = group.getAttribute("main")

                    implementation = self.__getFirstNode(
                        group, "implementation")

                    if implementation != None:
                        self.version = implementation.getAttribute("version")
                        if implementation.attributes["downloadsize"] != None:
                            try:
                                self.size = implementation.getAttribute(
                                    "downloadsize")
                            except:
                                pass

                    for node in implementation.getElementsByTagName(
                            "environment"):
                        try:
                            __readEnviroment(node)
                        except:
                            pass

                    for node in implementation.getElementsByTagName("archive"):
                        try:
                            ki = KlikIngredientPackage(
                                node.getAttribute("href"),
                                node.getAttribute("name"),
                                node.getAttribute("md5"))
                            self.packages.append(ki)
                        except:
                            pass

                    preflight = self.__getFirstNode(implementation,
                                                    "klik-preflight")
                    self.__readActions(preflight, self.preflight)

                    postflight = self.__getFirstNode(implementation,
                                                     "klik-postflight")
                    self.__readActions(postflight, self.postflight)

                    prerun = self.__getFirstNode(implementation, "klik-prerun")
                    self.__readActions(prerun, self.prerun)

                    postrun = self.__getFirstNode(implementation,
                                                  "klik-postrun")
                    self.__readActions(postrun, self.postrun)

                return
        elif error != None:
            # hack to trim quotes... why does this happen?
            raise SafeException(self.__getNodeValue(error, ""))
            return

        raise Exception("XML document does not appear to be a valid recipe")
예제 #10
0
파일: recipe.py 프로젝트: probonopd/klik
					preflight = self.__getFirstNode(implementation, "klik-preflight")
					self.__readActions( preflight, self.preflight)

					postflight = self.__getFirstNode(implementation, "klik-postflight")
					self.__readActions( postflight, self.postflight)

					prerun = self.__getFirstNode(implementation, "klik-prerun")
					self.__readActions( prerun, self.prerun)

					postrun = self.__getFirstNode(implementation, "klik-postrun")
					self.__readActions( postrun, self.postrun)

				return
		elif error != None:
			# hack to trim quotes... why does this happen?
			raise SafeException( self.__getNodeValue( error, "") )
			return

		raise Exception("XML document does not appear to be a valid recipe")


	def __readEnviroment( self, node ):
		name = node.getAttribute( "name" )

		if name != None and name != "":
			env = Enviroment()
			env.name = name
			env.insert = node.getAttribute( "insert" )
			env.mode = node.getAttribute( "mode" )
			env.default = node.getAttribute( "default" )