├── .coveragerc ├── .github └── workflows │ └── python-package.yml ├── .gitignore ├── .travis.yml ├── AUTHORS ├── CONTRIBUTING.md ├── LICENSE ├── MANIFEST.in ├── NEWS.txt ├── Pipfile ├── Pipfile.lock ├── README.rst ├── Vagrantfile ├── cpe ├── __init__.py ├── __meta__.py ├── comp │ ├── __init__.py │ ├── cpecomp.py │ ├── cpecomp1_1.py │ ├── cpecomp2_2.py │ ├── cpecomp2_3.py │ ├── cpecomp2_3_fs.py │ ├── cpecomp2_3_uri.py │ ├── cpecomp2_3_uri_edpacked.py │ ├── cpecomp2_3_wfn.py │ ├── cpecomp_anyvalue.py │ ├── cpecomp_empty.py │ ├── cpecomp_logical.py │ ├── cpecomp_notapplicable.py │ ├── cpecomp_simple.py │ └── cpecomp_undefined.py ├── cpe.py ├── cpe1_1.py ├── cpe2_2.py ├── cpe2_3.py ├── cpe2_3_fs.py ├── cpe2_3_uri.py ├── cpe2_3_wfn.py ├── cpelang.py ├── cpelang2_2.py ├── cpelang2_3.py ├── cpeset.py ├── cpeset1_1.py ├── cpeset2_2.py └── cpeset2_3.py ├── docs ├── Makefile ├── _static │ ├── cpe │ │ ├── cpe_model_all.png │ │ ├── cpe_model_all.pyns │ │ ├── cpe_model_all.pyns.pdf │ │ ├── cpe_model_public.png │ │ ├── cpe_model_public.pyns │ │ └── cpe_model_public.pyns.pdf │ ├── cpe_logo.gif │ ├── cpecomp │ │ ├── cpecomp_model_all.png │ │ ├── cpecomp_model_all.pyns │ │ ├── cpecomp_model_all.pyns.pdf │ │ ├── cpecomp_model_public.png │ │ ├── cpecomp_model_public.pyns │ │ └── cpecomp_model_public.pyns.pdf │ ├── cpelang │ │ ├── cpelang_model_all.png │ │ ├── cpelang_model_all.pyns │ │ ├── cpelang_model_all.pyns.pdf │ │ ├── cpelang_model_public.png │ │ ├── cpelang_model_public.pyns │ │ └── cpelang_model_public.pyns.pdf │ ├── cpeset │ │ ├── cpeset_model_all.png │ │ ├── cpeset_model_all.pyns │ │ ├── cpeset_model_all.pyns.pdf │ │ ├── cpeset_model_public.png │ │ ├── cpeset_model_public.pyns │ │ └── cpeset_model_public.pyns.pdf │ └── matching.png ├── bugtracker.rst ├── compatibility.rst ├── conf.py ├── cpeversions.rst ├── examples.rst ├── index.rst ├── install.rst ├── intro.rst ├── issues.rst ├── make.bat ├── model.rst ├── model │ ├── cpecomphierarchy.rst │ ├── cpecomphierarchy │ │ ├── cpecomp.rst │ │ ├── cpecomp1_1.rst │ │ ├── cpecomp2_2.rst │ │ ├── cpecomp2_3.rst │ │ ├── cpecomp2_3_fs.rst │ │ ├── cpecomp2_3_uri.rst │ │ ├── cpecomp2_3_uri_edpacked.rst │ │ ├── cpecomp2_3_wfn.rst │ │ ├── cpecomp_anyvalue.rst │ │ ├── cpecomp_empty.rst │ │ ├── cpecomp_logical.rst │ │ ├── cpecomp_notapplicable.rst │ │ ├── cpecomp_simple.rst │ │ └── cpecomp_undefined.rst │ ├── cpehierarchy.rst │ ├── cpehierarchy │ │ ├── cpe.rst │ │ ├── cpe1_1.rst │ │ ├── cpe2_2.rst │ │ ├── cpe2_3.rst │ │ ├── cpe2_3_fs.rst │ │ ├── cpe2_3_uri.rst │ │ └── cpe2_3_wfn.rst │ ├── cpelanghierarchy.rst │ ├── cpelanghierarchy │ │ ├── cpelang.rst │ │ ├── cpelang2_2.rst │ │ └── cpelang2_3.rst │ ├── cpesethierarchy.rst │ └── cpesethierarchy │ │ ├── cpeset.rst │ │ ├── cpeset1_1.rst │ │ ├── cpeset2_2.rst │ │ └── cpeset2_3.rst ├── references.rst └── todo.rst ├── requirements-dev.txt ├── setup.cfg ├── setup.py ├── tests ├── expression2_2.xml ├── expression2_3.json ├── expression2_3.xml ├── testfile_cpe.txt ├── testfile_cpe2_3.txt ├── testfile_cpe2_3_fs.txt ├── testfile_cpe2_3_uri.txt ├── testfile_cpe2_3_wfn.txt ├── testfile_cpecomp.txt ├── testfile_cpecomp1_1.txt ├── testfile_cpecomp2_2.txt ├── testfile_cpecomp2_3_fs.txt ├── testfile_cpecomp2_3_uri.txt ├── testfile_cpecomp2_3_wfn.txt ├── testfile_cpecomp_anyvalue.txt ├── testfile_cpecomp_empty.txt ├── testfile_cpecomp_logical.txt ├── testfile_cpecomp_notapplicable.txt ├── testfile_cpecomp_simple.txt ├── testfile_cpecomp_undefined.txt ├── testfile_cpelang2_2.txt ├── testfile_cpelang2_3.txt ├── testfile_cpeset1_1.txt ├── testfile_cpeset2_2.txt ├── testfile_cpeset2_3.txt └── unit │ ├── test_bugfixes.py │ ├── test_cpe.py │ ├── test_cpe1_1.py │ ├── test_cpe2_2.py │ └── test_cpe2_3_uri_sparse.py ├── tox.ini └── utils └── provision.sh /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | branch = True 3 | -------------------------------------------------------------------------------- /.github/workflows/python-package.yml: -------------------------------------------------------------------------------- 1 | # This workflow will install Python dependencies, run tests and lint with a variety of Python versions 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python 3 | 4 | name: Python package 5 | 6 | on: 7 | push: 8 | branches: [ "develop" ] 9 | pull_request: 10 | branches: [ "develop" ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | strategy: 17 | fail-fast: false 18 | matrix: 19 | python-version: ["3.8", "3.9", "3.10"] 20 | 21 | steps: 22 | - uses: actions/checkout@v3 23 | - name: Set up Python ${{ matrix.python-version }} 24 | uses: actions/setup-python@v3 25 | with: 26 | python-version: ${{ matrix.python-version }} 27 | - name: Install dependencies 28 | run: | 29 | python -m pip install --upgrade pip 30 | python -m pip install flake8 pytest 31 | pip install -r requirements-dev.txt 32 | - name: Lint with flake8 33 | run: | 34 | # stop the build if there are Python syntax errors or undefined names 35 | flake8 cpe --count --select=E9,F63,F7,F82 --show-source --statistics 36 | # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide 37 | # flake8 cpe --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics 38 | - name: Test with pytest 39 | run: | 40 | python3 -m pytest 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | *.swp 3 | 4 | # C extensions 5 | *.so 6 | 7 | # Packages 8 | *.egg 9 | *.egg-info 10 | dist 11 | build 12 | eggs 13 | parts 14 | bin 15 | var 16 | sdist 17 | develop-eggs 18 | .installed.cfg 19 | lib 20 | lib64 21 | __pycache__ 22 | 23 | # Installer logs 24 | pip-log.txt 25 | 26 | # Unit test / coverage reports 27 | .coverage 28 | .tox 29 | nosetests.xml 30 | 31 | # Translations 32 | *.mo 33 | 34 | # Mr Developer 35 | .mr.developer.cfg 36 | .project 37 | .pydevproject 38 | docs/_build/ 39 | 40 | coverage.xml 41 | htmlcov 42 | 43 | .idea 44 | venv 45 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "2.7" 4 | - "3.4" 5 | - "3.5" 6 | - "3.6" 7 | - "pypy" 8 | install: 9 | - pip install -r requirements-dev.txt 10 | - pip install coveralls 11 | - python setup.py develop 12 | script: 13 | - cd tests/ 14 | - py.test --cov cpe --doctest-modules . 15 | - cd ../docs/ 16 | - sphinx-build -W -b html -d /tmp/doctrees . /tmp/html 17 | after_success: 18 | - coveralls 19 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | 2 | The PRIMARY AUTHORS are (and/or have been): 3 | 4 | * Alejandro Galindo (@galindale) 5 | * Roberto Abdelkader Martínez Pérez (@nilp0inter) 6 | 7 | List of MUCH-APPRECIATED CONTRIBUTORS: 8 | 9 | * @TauPan. https://github.com/TauPan 10 | * @orf. https://github.com/orf 11 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | How to contribute 2 | ================= 3 | 4 | Getting started 5 | --------------- 6 | 7 | * Check for open issues or open a fresh issue to start a discussion around a feature, idea or a bug. 8 | * Fork the repository on GitHub. 9 | * Clone your fork on your computer. 10 | 11 | 12 | Installing dependencies 13 | ----------------------- 14 | 15 | * Run the following command to install the developer dendencies: 16 | ```bash 17 | $ pip install -r requirements-dev.txt 18 | ``` 19 | 20 | Developer workflow 21 | ------------------ 22 | 23 | 1 Create a topic branch from the develop branch. 24 | ```bash 25 | $ git checkout -b my_new_feature develop 26 | ``` 27 | * Run the test-suite and verify everything is fine: 28 | ```bash 29 | py.test . 30 | ``` 31 | 32 | 2 Write your code and a test that the bug was fixed or that the feature works as expected. 33 | 34 | 3 Make sure to add yourself to AUTHORS. ;) 35 | 36 | 4 Run the tests again. 37 | 38 | 5 Send a pull request and bug the maintainer until it gets merged and published. 39 | 40 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include AUTHORS LICENSE NEWS.txt README.rst 2 | include tox.ini .coveragerc 3 | 4 | recursive-include tests *.txt *.xml *.py 5 | recursive-include requirements *.txt 6 | recursive-include docs * 7 | 8 | prune docs/_build 9 | global-exclude *.pyc 10 | global-exclude __pycache__ 11 | -------------------------------------------------------------------------------- /NEWS.txt: -------------------------------------------------------------------------------- 1 | News 2 | ==== 3 | 4 | 1.3.1 5 | ----- 6 | 7 | * Fix invalid/deprecated escape sequences #63. 8 | 9 | 1.3.0 10 | ----- 11 | 12 | * Primitive implementation of NVD JSON configuration #55. 13 | * Fix typo in CPESet2_3 version exception #33. 14 | * Fixed problem when comparing with _compare_strings #41. 15 | * Updated _VALUE_PATTERN for CPE 2.2 #56. 16 | * Fix DeprecationWarning issues in Python code #57. 17 | 18 | 1.2.1 19 | ----- 20 | 21 | * Fixed #28. 22 | * Some tests marked as xfail until we carify the proper behaviour for 23 | ANY values. 24 | 25 | 26 | 1.2.0 27 | ----- 28 | 29 | * Python3 support. 30 | * Using tox for testing Python2.7 and Python3.4. 31 | * Test directory outside of the package. 32 | * Fixed sphinx warnings. 33 | * Fixed problems parsing colons. Thanks to @damiengermonville. 34 | * Using a new system for package metadata management. 35 | 36 | 37 | 1.1.0 38 | ----- 39 | 40 | * Closed pending issues: 41 | * Fix wildcard matching #6 42 | * fix multiple %01 wildcards #8 43 | * turn CPESet2_3.compare_wfns into a generator #9 44 | * correctly transform not applicable values for edition #11 45 | * Contributing.md file. 46 | 47 | 48 | 1.0.6 49 | ----- 50 | 51 | * Using OrderedDict for `_system_and_parts` and `_CPE_VERSIONS`. For force evaluation order. Tests was failing randomly. 52 | * Changed testing tools: tox + pytest + coverage. 53 | * Changed license to LGPLv3. 54 | 55 | 56 | 1.0.5 57 | ----- 58 | 59 | * Fixed an issue reported by @TauPan. Added cpe.comp as sub-package. https://github.com/galindale/cpe/pull/2. (@TauPan) 60 | 61 | 62 | 1.0.4 63 | ----- 64 | 65 | New funtionality has not added, only there are small changes: 66 | 67 | * Add NEWS.txt file with the updates in the cpe package releases. 68 | * Added issue about language attribute in CPE Names in documentation. 69 | * Changed some files to follow PEP8. 70 | * Fixed language validation method in CPE components with version 2.3. 71 | * Added integration with travis-ci and version badge and Pypi shield/pin images. 72 | * Added option "packages" in setup.py. 73 | 74 | 75 | 1.0.3 76 | ----- 77 | 78 | * Fixed an error to check logical values in parsing with CPE names with WFN style. 79 | * Fixed example about convertion methods between CPE styles in naming section. 80 | 81 | 82 | 1.0.2 83 | ----- 84 | 85 | * New release. 86 | 87 | 88 | 1.0.1 89 | ----- 90 | 91 | * New release. 92 | 93 | 94 | 1.0.0 95 | ----- 96 | 97 | * New release. 98 | 99 | 100 | 0.1.0 101 | ----- 102 | 103 | * Starting development. 104 | -------------------------------------------------------------------------------- /Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | url = "https://pypi.org/simple" 3 | verify_ssl = true 4 | name = "pypi" 5 | 6 | [packages] 7 | tox = "*" 8 | 9 | [dev-packages] 10 | pytest = "*" 11 | pytest-cov = "*" 12 | Sphinx = "==1.2.2" 13 | ipdb = "*" 14 | 15 | [requires] 16 | python_version = "3.7" 17 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | .. image:: http://cpe.mitre.org/images/cpe_logo.gif 2 | :alt: CPE Logo 3 | 4 | Common Platform Enumeration for Python 5 | -------------------------------------- 6 | 7 | *CPE* (this code) is a LGPL licensed Python package, implementing the 8 | CPE standards. 9 | 10 | 11 | About the CPE standard 12 | ---------------------- 13 | 14 | Common Platform Enumeration (CPE) is a standardized method of describing 15 | and identifying classes of applications, operating systems, and hardware 16 | devices present among an enterprise's computing assets. 17 | 18 | For more information, please visit the official website of CPE, 19 | developed by `MITRE`_ and maintained by `NIST`_. 20 | 21 | 22 | Features 23 | -------- 24 | 25 | - CPE rich comparison. 26 | - CPE cross-version conversion. 27 | - CPE Language parsing and evaluation. 28 | - LGPL Licensed. 29 | - Semantic versioning. 30 | - Tests. 31 | 32 | 33 | Installation |Version| |TravisCI_master| 34 | ---------------------------------------- 35 | 36 | To install `CPE` execute: 37 | 38 | .. code-block:: bash 39 | 40 | $ pip install cpe 41 | 42 | The latest stable version is always in `PyPI`_. 43 | 44 | 45 | Documentation 46 | ------------- 47 | 48 | Documentation is available at `ReadTheDocs`_. 49 | 50 | 51 | Compatibility 52 | ------------- 53 | 54 | - Python: 2.7, 3.4 55 | - CPE: 1.1, 2.2, 2.3 56 | - CPE Formats: WFN, URI, FS. 57 | 58 | 59 | Contribute |Coverage| |TravisCI_develop| |Waffle.IO_ready| 60 | ---------------------------------------------------------- 61 | 62 | Follow the steps on the `how to contribute`_ document. 63 | 64 | .. _PyPI: https://pypi.python.org/pypi/cpe/ 65 | .. _MITRE: http://cpe.mitre.org/ 66 | .. _NIST: http://nvd.nist.gov/cpe.cfm 67 | .. _ReadTheDocs: https://cpe.readthedocs.org/en/latest/ 68 | .. _GitHub: https://github.com/nilp0inter/cpe 69 | .. _How to contribute: https://github.com/nilp0inter/cpe/blob/develop/CONTRIBUTING.md 70 | 71 | 72 | .. |TravisCI_master| image:: https://travis-ci.org/nilp0inter/cpe.svg?branch=master 73 | :target: https://travis-ci.org/nilp0inter/cpe 74 | :alt: Build Status (master) 75 | 76 | 77 | .. |TravisCI_develop| image:: https://travis-ci.org/nilp0inter/cpe.svg?branch=develop 78 | :target: https://travis-ci.org/nilp0inter/cpe 79 | :alt: Build Status (develop) 80 | 81 | .. |Waffle.IO_ready| image:: https://badge.waffle.io/nilp0inter/cpe.png?label=ready&title=Ready 82 | :target: https://waffle.io/nilp0inter/cpe 83 | :alt: Stories in Ready 84 | 85 | .. |Coverage| image:: https://coveralls.io/repos/nilp0inter/cpe/badge.png?branch=develop 86 | :target: https://coveralls.io/r/nilp0inter/cpe?branch=develop 87 | :alt: Coverage Status 88 | 89 | .. |Downloads| image:: https://pypip.in/d/cpe/badge.png 90 | :target: https://crate.io/packages/cpe 91 | :alt: Downloads 92 | 93 | .. |Version| image:: https://camo.githubusercontent.com/8369bedde5c3455e907e9ddf9b06751af7cbbc28/68747470733a2f2f62616467652e667572792e696f2f70792f6370652e706e67 94 | :target: http://badge.fury.io/py/cpe 95 | :alt: Version 96 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! 5 | VAGRANTFILE_API_VERSION = "2" 6 | 7 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 8 | config.vm.box = "Puppetlabs Ubuntu 12.04.2 x86_64, VBox 4.2.10" 9 | 10 | # From: http://www.vagrantbox.es/ 11 | config.vm.box_url = "http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-server-12042-x64-vbox4210.box" 12 | 13 | config.vm.provision :shell, :path => "utils/provision.sh" 14 | 15 | end 16 | -------------------------------------------------------------------------------- /cpe/__init__.py: -------------------------------------------------------------------------------- 1 | from .cpe import CPE 2 | -------------------------------------------------------------------------------- /cpe/__meta__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from __future__ import unicode_literals 4 | from collections import namedtuple 5 | 6 | # Developer definition. 7 | # AFAIK: A human being capable of turn pizza & coke into code. 8 | Developer = namedtuple("Developer", ("name", "email")) 9 | 10 | 11 | __all__ = [ 12 | "__packagename__", 13 | "__version__", 14 | "__summary__", 15 | "__url__", 16 | "__author__", 17 | "__email__", 18 | "__license__" 19 | ] 20 | 21 | DEVELOPERS = { 22 | "nilp0inter": Developer("Roberto Abdelkader Martínez Pérez", 23 | "robertomartinezp@gmail.com"), 24 | "galindale": Developer("Alejandro Galindo García", 25 | "alejandro.galindo@i4s.com"), 26 | "creekorful": Developer("Aloïs Micard", 27 | "alois@micard.lu") 28 | } 29 | 30 | __packagename__ = "cpe" 31 | __version__ = "1.3.1" 32 | __summary__ = "CPE: Common Platform Enumeration for Python" 33 | __keywords__ = "cpe identification naming matching standard specification mitre nist" 34 | __url__ = "https://github.com/nilp0inter/cpe" 35 | __author__ = ", ".join([ 36 | DEVELOPERS["nilp0inter"].name, 37 | DEVELOPERS["galindale"].name, 38 | DEVELOPERS["creekorful"].name]) 39 | __email__ = ", ".join([ 40 | DEVELOPERS["nilp0inter"].email, 41 | DEVELOPERS["galindale"].email, 42 | DEVELOPERS["creekorful"].email]) 43 | __maintainer__ = DEVELOPERS["nilp0inter"].name 44 | __maintainer_email__ = DEVELOPERS["nilp0inter"].email 45 | __license__ = "LGPLv3" 46 | -------------------------------------------------------------------------------- /cpe/comp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilp0inter/cpe/50ba2ee28b5d6b24fa2c5b1493de9de953ca7dce/cpe/comp/__init__.py -------------------------------------------------------------------------------- /cpe/comp/cpecomp2_2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | This file is part of cpe package. 6 | 7 | This module allows to store the value of the components of a CPE name 8 | of version 2.2 of CPE (Common Platform Enumeration) specification. 9 | 10 | Copyright (C) 2013 Alejandro Galindo García, Roberto Abdelkader Martínez Pérez 11 | 12 | This program is free software: you can redistribute it and/or modify 13 | it under the terms of the GNU Lesser General Public License as published by 14 | the Free Software Foundation, either version 3 of the License, or 15 | (at your option) any later version. 16 | 17 | This program is distributed in the hope that it will be useful, 18 | but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | GNU Lesser General Public License for more details. 21 | 22 | You should have received a copy of the GNU Lesser General Public License 23 | along with this program. If not, see . 24 | 25 | For any problems using the cpe package, or general questions and 26 | feedback about it, please contact: 27 | 28 | - Alejandro Galindo García: galindo.garcia.alejandro@gmail.com 29 | - Roberto Abdelkader Martínez Pérez: robertomartinezp@gmail.com 30 | """ 31 | 32 | from .cpecomp_simple import CPEComponentSimple 33 | 34 | import re 35 | 36 | 37 | class CPEComponent2_2(CPEComponentSimple): 38 | """ 39 | Represents a component of version 2.2 of CPE specification. 40 | 41 | TEST: simple value 42 | 43 | >>> value = "microsoft" 44 | >>> comp = CPEComponent2_2(value, CPEComponentSimple.ATT_VENDOR) 45 | """ 46 | 47 | ############### 48 | # CONSTANTS # 49 | ############### 50 | 51 | #: Pattern used to check the value of component 52 | _VALUE_PATTERN = r"^([\d\w\._\-~%\\/]+)$" 53 | 54 | #: Separator of components of CPE name with URI style 55 | SEPARATOR_COMP = ":" 56 | 57 | #: Characters of version 2.2 of CPE name to convert 58 | #: to standard value (WFN value) 59 | NON_STANDARD_VALUES = [".", "-", "~", "%"] 60 | 61 | # Logical values in string format 62 | 63 | #: Logical value associated with a undefined component of CPE Name 64 | VALUE_UNDEFINED = None 65 | 66 | #: Logical value associated with a component without value set 67 | VALUE_EMPTY = "" 68 | 69 | ############### 70 | # VARIABLES # 71 | ############### 72 | 73 | #: Compilation of pattern used to check the value of component 74 | _value_rxc = re.compile(_VALUE_PATTERN) 75 | 76 | #################### 77 | # OBJECT METHODS # 78 | #################### 79 | 80 | def __repr__(self): 81 | """ 82 | Returns a unambiguous representation of CPE component. 83 | 84 | :returns: Representation of CPE component as string 85 | :rtype: string 86 | """ 87 | 88 | return "{0}({1})".format(self.__class__.__name__, self.get_value()) 89 | 90 | def _decode(self): 91 | """ 92 | Convert the encoded value of component to standard value (WFN value). 93 | """ 94 | 95 | result = [] 96 | idx = 0 97 | s = self._encoded_value 98 | 99 | while (idx < len(s)): 100 | # Get the idx'th character of s 101 | c = s[idx] 102 | 103 | if (c in CPEComponent2_2.NON_STANDARD_VALUES): 104 | # Escape character 105 | result.append("\\") 106 | result.append(c) 107 | else: 108 | # Do nothing 109 | result.append(c) 110 | 111 | idx += 1 112 | 113 | self._standard_value = "".join(result) 114 | 115 | def _is_valid_value(self): 116 | """ 117 | Return True if the value of component in generic attribute is valid, 118 | and otherwise False. 119 | 120 | :returns: True if value is valid, False otherwise 121 | :rtype: boolean 122 | """ 123 | 124 | comp_str = self._encoded_value 125 | return CPEComponent2_2._value_rxc.match(comp_str) is not None 126 | 127 | if __name__ == "__main__": 128 | import doctest 129 | doctest.testmod() 130 | doctest.testfile("../tests/testfile_cpecomp2_2.txt") 131 | -------------------------------------------------------------------------------- /cpe/comp/cpecomp2_3_fs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | This file is part of cpe package. 6 | 7 | This module allows to store the value of the components of a CPE name 8 | of version 2.3 of CPE (Common Platform Enumeration) specification 9 | with formatted string style. 10 | 11 | Copyright (C) 2013 Alejandro Galindo García, Roberto Abdelkader Martínez Pérez 12 | 13 | This program is free software: you can redistribute it and/or modify 14 | it under the terms of the GNU Lesser General Public License as published by 15 | the Free Software Foundation, either version 3 of the License, or 16 | (at your option) any later version. 17 | 18 | This program is distributed in the hope that it will be useful, 19 | but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | GNU Lesser General Public License for more details. 22 | 23 | You should have received a copy of the GNU Lesser General Public License 24 | along with this program. If not, see . 25 | 26 | For any problems using the cpe package, or general questions and 27 | feedback about it, please contact: 28 | 29 | - Alejandro Galindo García: galindo.garcia.alejandro@gmail.com 30 | - Roberto Abdelkader Martínez Pérez: robertomartinezp@gmail.com 31 | """ 32 | 33 | from .cpecomp2_3 import CPEComponent2_3 34 | from .cpecomp2_3_wfn import CPEComponent2_3_WFN 35 | from .cpecomp_simple import CPEComponentSimple 36 | 37 | import re 38 | 39 | 40 | class CPEComponent2_3_FS(CPEComponent2_3): 41 | """ 42 | Represents a component of version 2.3 of CPE specification with URI style. 43 | """ 44 | 45 | ############### 46 | # CONSTANTS # 47 | ############### 48 | 49 | # Patterns used to check the value of component 50 | _UNRESERVED = r"\w|\.|\-" 51 | _PUNC = r"\!|\"|\;|\#|\$|\%|\&|\'|\(|\)|\+|\,|\/|\:|\<|\=|\>|\@|\[|\]|\^|\`|\{|\||\}|\~|\-" 52 | 53 | #: Separator of components of CPE name with URI style 54 | SEPARATOR_COMP = ":" 55 | 56 | #: Separator of language parts: language and region 57 | SEPARATOR_LANG = "-" 58 | 59 | # Logical values in string format 60 | 61 | #: Logical value associated with a any value logical value 62 | VALUE_ANY = "*" 63 | 64 | #: Logical value associated with a not applicable logical value 65 | VALUE_NA = "-" 66 | 67 | #: Constant associated with wildcard to indicate a sequence of characters 68 | WILDCARD_MULTI = CPEComponent2_3_WFN.WILDCARD_MULTI 69 | #: Constant associated with wildcard to indicate a character 70 | WILDCARD_ONE = CPEComponent2_3_WFN.WILDCARD_ONE 71 | 72 | ############### 73 | # VARIABLES # 74 | ############### 75 | 76 | # Compilation of regular expression associated with value of CPE part 77 | _logical = r"(\{0}|{1})".format(VALUE_ANY, VALUE_NA) 78 | _quest = r"\{0}".format(WILDCARD_ONE) 79 | _asterisk = r"\{0}".format(WILDCARD_MULTI) 80 | _special = "{0}|{1}".format(_quest, _asterisk) 81 | _spec_chrs = "{0}+|{1}".format(_quest, _asterisk) 82 | _quoted = r"\\(\\" + "|{0}|{1})".format(_special, _PUNC) 83 | _avstring = "{0}|{1}".format(_UNRESERVED, _quoted) 84 | _value_string_pattern = "^(({0}+|{1}*({2})+|{3}({4})+)({5})?|{6})$".format( 85 | _quest, _quest, _avstring, _asterisk, _avstring, _spec_chrs, _logical) 86 | 87 | _part_value_rxc = re.compile(_value_string_pattern) 88 | 89 | #################### 90 | # OBJECT METHODS # 91 | #################### 92 | 93 | def _decode(self): 94 | """ 95 | Convert the characters of string s to standard value (WFN value). 96 | Inspect each character in value of component. Copy quoted characters, 97 | with their escaping, into the result. Look for unquoted non 98 | alphanumerics and if not "*" or "?", add escaping. 99 | 100 | :exception: ValueError - invalid character in value of component 101 | """ 102 | 103 | result = [] 104 | idx = 0 105 | s = self._encoded_value 106 | embedded = False 107 | 108 | errmsg = [] 109 | errmsg.append("Invalid character '") 110 | 111 | while (idx < len(s)): 112 | c = s[idx] # get the idx'th character of s 113 | errmsg.append(c) 114 | errmsg.append("'") 115 | errmsg_str = "".join(errmsg) 116 | 117 | if (CPEComponentSimple._is_alphanum(c)): 118 | # Alphanumeric characters pass untouched 119 | result.append(c) 120 | idx += 1 121 | embedded = True 122 | continue 123 | 124 | if c == "\\": 125 | # Anything quoted in the bound string stays quoted 126 | # in the unbound string. 127 | result.append(s[idx: idx + 2]) 128 | idx += 2 129 | embedded = True 130 | continue 131 | 132 | if (c == CPEComponent2_3_FS.WILDCARD_MULTI): 133 | # An unquoted asterisk must appear at the beginning or 134 | # end of the string. 135 | if (idx == 0) or (idx == (len(s) - 1)): 136 | result.append(c) 137 | idx += 1 138 | embedded = True 139 | continue 140 | else: 141 | raise ValueError(errmsg_str) 142 | 143 | if (c == CPEComponent2_3_FS.WILDCARD_ONE): 144 | # An unquoted question mark must appear at the beginning or 145 | # end of the string, or in a leading or trailing sequence: 146 | # - ? legal at beginning or end 147 | # - embedded is false, so must be preceded by ? 148 | # - embedded is true, so must be followed by ? 149 | if (((idx == 0) or (idx == (len(s) - 1))) or 150 | ((not embedded) and (s[idx - 1] == CPEComponent2_3_FS.WILDCARD_ONE)) or 151 | (embedded and (s[idx + 1] == CPEComponent2_3_FS.WILDCARD_ONE))): 152 | result.append(c) 153 | idx += 1 154 | embedded = False 155 | continue 156 | else: 157 | raise ValueError(errmsg_str) 158 | 159 | # all other characters must be quoted 160 | result.append("\\") 161 | result.append(c) 162 | idx += 1 163 | embedded = True 164 | 165 | self._standard_value = "".join(result) 166 | 167 | def _is_valid_value(self): 168 | """ 169 | Return True if the value of component in generic attribute is valid, 170 | and otherwise False. 171 | 172 | :returns: True if value is valid, False otherwise 173 | :rtype: boolean 174 | """ 175 | 176 | comp_str = self._standard_value[0] 177 | return CPEComponent2_3_FS._part_value_rxc.match(comp_str) is not None 178 | 179 | if __name__ == "__main__": 180 | import doctest 181 | doctest.testmod() 182 | doctest.testfile("../tests/testfile_cpecomp2_3_fs.txt") 183 | -------------------------------------------------------------------------------- /cpe/comp/cpecomp2_3_uri_edpacked.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | This file is part of cpe package. 6 | 7 | This module allows to store the value of the packed edition component 8 | of a CPE name of version 2.3 of CPE (Common Platform Enumeration) 9 | specification with Universal Resource Identifier (URI) style. 10 | 11 | Copyright (C) 2013 Alejandro Galindo García, Roberto Abdelkader Martínez Pérez 12 | 13 | This program is free software: you can redistribute it and/or modify 14 | it under the terms of the GNU Lesser General Public License as published by 15 | the Free Software Foundation, either version 3 of the License, or 16 | (at your option) any later version. 17 | 18 | This program is distributed in the hope that it will be useful, 19 | but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | GNU Lesser General Public License for more details. 22 | 23 | You should have received a copy of the GNU Lesser General Public License 24 | along with this program. If not, see . 25 | 26 | For any problems using the cpe package, or general questions and 27 | feedback about it, please contact: 28 | 29 | - Alejandro Galindo García: galindo.garcia.alejandro@gmail.com 30 | - Roberto Abdelkader Martínez Pérez: robertomartinezp@gmail.com 31 | """ 32 | 33 | from .cpecomp2_3_uri import CPEComponent2_3_URI 34 | 35 | 36 | class CPEComponent2_3_URI_edpacked(CPEComponent2_3_URI): 37 | """ 38 | Represents a packd edition component of version 2.3 of CPE 39 | specification with URI style. 40 | """ 41 | 42 | ############### 43 | # CONSTANTS # 44 | ############### 45 | 46 | #: Separator of components of an edition attribute packed 47 | SEPARATOR_COMP = "~" 48 | 49 | #################### 50 | # OBJECT METHODS # 51 | #################### 52 | 53 | def __init__(self, comp_str): 54 | """ 55 | Store the value of component. 56 | 57 | :param string comp_str: value of component value 58 | :returns: None 59 | :exception: ValueError - incorrect value of component 60 | """ 61 | 62 | self.set_value(comp_str) 63 | 64 | def _decode(self): 65 | """ 66 | The decoding of the value of this type of component is not necesaary. 67 | """ 68 | 69 | pass 70 | 71 | def _is_valid_edition(self): 72 | """ 73 | This function is not necesaary in this component. 74 | 75 | :returns: True 76 | :rtype: boolean 77 | """ 78 | 79 | True 80 | 81 | def _is_valid_value(self): 82 | """ 83 | This function is not necesaary in this component. 84 | 85 | :returns: True 86 | :rtype: boolean 87 | """ 88 | 89 | True 90 | 91 | def set_value(self, comp_str): 92 | """ 93 | Set the value of component. 94 | 95 | :param string comp_str: value of component 96 | :returns: None 97 | :exception: ValueError - incorrect value of component 98 | """ 99 | 100 | self._is_negated = False 101 | self._encoded_value = comp_str 102 | self._standard_value = super( 103 | CPEComponent2_3_URI_edpacked, self)._decode() 104 | 105 | if __name__ == "__main__": 106 | import doctest 107 | doctest.testmod() 108 | -------------------------------------------------------------------------------- /cpe/comp/cpecomp2_3_wfn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | This file is part of cpe package. 6 | 7 | This module allows to store the value of the components of a CPE name 8 | of version 2.3 of CPE (Common Platform Enumeration) specification with 9 | Well-Formed Name (WFN) style. 10 | 11 | Copyright (C) 2013 Alejandro Galindo García, Roberto Abdelkader Martínez Pérez 12 | 13 | This program is free software: you can redistribute it and/or modify 14 | it under the terms of the GNU Lesser General Public License as published by 15 | the Free Software Foundation, either version 3 of the License, or 16 | (at your option) any later version. 17 | 18 | This program is distributed in the hope that it will be useful, 19 | but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | GNU Lesser General Public License for more details. 22 | 23 | You should have received a copy of the GNU Lesser General Public License 24 | along with this program. If not, see . 25 | 26 | For any problems using the cpe package, or general questions and 27 | feedback about it, please contact: 28 | 29 | - Alejandro Galindo García: galindo.garcia.alejandro@gmail.com 30 | - Roberto Abdelkader Martínez Pérez: robertomartinezp@gmail.com 31 | """ 32 | 33 | from .cpecomp2_3 import CPEComponent2_3 34 | 35 | import re 36 | 37 | 38 | class CPEComponent2_3_WFN(CPEComponent2_3): 39 | """ 40 | Represents a component of version 2.3 of CPE specification with WFN style. 41 | """ 42 | 43 | ############### 44 | # CONSTANTS # 45 | ############### 46 | 47 | # Patterns used to check the value of component 48 | _ESCAPE = r"\\" 49 | _PUNC_NO_DASH = r"\!|\"|\;|\#|\$|\%|\&|\'|\(|\)|\+|\,|\.|\/|\:|\<|\=|\>|\@|\[|\]|\^|\`|\{|\||\}|\~" 50 | 51 | #: Separator of components of CPE name with URI style 52 | SEPARATOR_COMP = ", " 53 | 54 | #: Separator of attribute and value in pairs of component 55 | SEPARATOR_PAIR = "=" 56 | 57 | #: Separator of language parts: language and region 58 | SEPARATOR_LANG = r"\-" 59 | 60 | # Logical values in string format 61 | 62 | #: Logical value associated with a any value logical value 63 | VALUE_ANY = "ANY" 64 | 65 | #: Logical value associated with a not applicable logical value 66 | VALUE_NA = "NA" 67 | 68 | #: Constant associated with wildcard to indicate a sequence of characters 69 | WILDCARD_MULTI = "*" 70 | #: Constant associated with wildcard to indicate a character 71 | WILDCARD_ONE = "?" 72 | 73 | ############### 74 | # VARIABLES # 75 | ############### 76 | 77 | _spec1 = r"\{0}".format(WILDCARD_ONE) 78 | _spec2 = r"\{0}".format(WILDCARD_MULTI) 79 | _spec_chrs = "{0}+|{1}".format(_spec1, _spec2) 80 | _special = "{0}|{1}".format(_spec1, _spec2) 81 | _punc_w_dash = "{0}|-".format(_PUNC_NO_DASH) 82 | _quoted1 = "{0}({1}|{2}|{3})".format(_ESCAPE, _ESCAPE, _special, 83 | _PUNC_NO_DASH) 84 | _quoted2 = "{0}({1}|{2}|{3})".format(_ESCAPE, _ESCAPE, 85 | _special, _punc_w_dash) 86 | _body1 = r"\w|{0}".format(_quoted1) 87 | _body2 = r"\w|{0}".format(_quoted2) 88 | _body = "(({0})({1})*)|{2}({3})+".format(_body1, _body2, _body2, _body2) 89 | _avstring_pattern = "^((({0})|(({1})({2})*))({3})?)$".format(_body, 90 | _spec_chrs, 91 | _body2, 92 | _spec_chrs) 93 | 94 | _value_rxc = re.compile(_avstring_pattern) 95 | 96 | #################### 97 | # OBJECT METHODS # 98 | #################### 99 | 100 | def _decode(self): 101 | """ 102 | Convert the encoded value of component to standard value (WFN value) is 103 | not necessary in this case because the internal value is in WFN 104 | already. 105 | """ 106 | 107 | pass 108 | 109 | def _is_valid_value(self): 110 | """ 111 | Return True if the value of component in generic attribute is valid, 112 | and otherwise False. 113 | 114 | :returns: True if value is valid, False otherwise 115 | :rtype: boolean 116 | """ 117 | 118 | comp_str = self._standard_value 119 | return CPEComponent2_3_WFN._value_rxc.match(comp_str) is not None 120 | 121 | def get_value(self): 122 | """ 123 | Returns the encoded value of component. 124 | 125 | :returns: encoded value of component 126 | :rtype: string 127 | """ 128 | 129 | # Add double quotes 130 | return '"{0}"'.format(super(CPEComponent2_3_WFN, self).get_value()) 131 | 132 | def set_value(self, comp_str, comp_att): 133 | """ 134 | Set the value of component. 135 | 136 | :param string comp_str: value of component 137 | :param string comp_att: attribute associated with comp_str 138 | :returns: None 139 | :exception: ValueError - incorrect value of component 140 | """ 141 | 142 | # Del double quotes of value 143 | str = comp_str[1:-1] 144 | self._standard_value = str 145 | 146 | # Parse the value 147 | super(CPEComponent2_3_WFN, self).set_value(str, comp_att) 148 | 149 | if __name__ == "__main__": 150 | import doctest 151 | doctest.testmod() 152 | doctest.testfile("../tests/testfile_cpecomp2_3_wfn.txt") 153 | -------------------------------------------------------------------------------- /cpe/comp/cpecomp_anyvalue.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | This file is part of cpe package. 6 | 7 | This module allows to create a component of CPE name that represents any value. 8 | 9 | Copyright (C) 2013 Alejandro Galindo García, Roberto Abdelkader Martínez Pérez 10 | 11 | This program is free software: you can redistribute it and/or modify 12 | it under the terms of the GNU Lesser General Public License as published by 13 | the Free Software Foundation, either version 3 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU Lesser General Public License for more details. 20 | 21 | You should have received a copy of the GNU Lesser General Public License 22 | along with this program. If not, see . 23 | 24 | For any problems using the cpe package, or general questions and 25 | feedback about it, please contact: 26 | 27 | - Alejandro Galindo García: galindo.garcia.alejandro@gmail.com 28 | - Roberto Abdelkader Martínez Pérez: robertomartinezp@gmail.com 29 | """ 30 | 31 | from .cpecomp_logical import CPEComponentLogical 32 | 33 | 34 | class CPEComponentAnyValue(CPEComponentLogical): 35 | """ 36 | Represents a component of CPE name without a particular value, 37 | compatible with the components of all versions of CPE specification. 38 | 39 | For example, in version 2.3 of CPE specification, an component "any value" 40 | is other attribute in CPE name 41 | cpe:2.3:a:microsft:windows:xp:*:*:*:*:*:*:*. 42 | """ 43 | 44 | #################### 45 | # OBJECT METHODS # 46 | #################### 47 | 48 | def __eq__(self, other): 49 | """ 50 | Returns True if other (first element of operation) and 51 | self (second element of operation) are equal components, 52 | false otherwise. 53 | 54 | :param CPEComponent other: component to compare 55 | :returns: True if other == self, False otherwise 56 | :rtype: boolean 57 | """ 58 | 59 | from .cpecomp_empty import CPEComponentEmpty 60 | from .cpecomp_undefined import CPEComponentUndefined 61 | 62 | return (isinstance(other, CPEComponentUndefined) or 63 | isinstance(other, CPEComponentEmpty) or 64 | isinstance(other, CPEComponentAnyValue)) 65 | 66 | def __init__(self): 67 | """ 68 | Initializes the component. 69 | """ 70 | 71 | super(CPEComponentAnyValue, self).__init__( 72 | CPEComponentLogical._VALUE_INT_ANY) 73 | 74 | def __str__(self): 75 | """ 76 | Returns a human-readable representation of CPE component. 77 | 78 | :returns: Representation of CPE component as string 79 | :rtype: string 80 | """ 81 | 82 | return "" 83 | 84 | if __name__ == "__main__": 85 | import doctest 86 | doctest.testmod() 87 | doctest.testfile('../tests/testfile_cpecomp_anyvalue.txt') 88 | -------------------------------------------------------------------------------- /cpe/comp/cpecomp_empty.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | This file is part of cpe package. 6 | 7 | This module allows to create an empty component of CPE name. 8 | 9 | Copyright (C) 2013 Alejandro Galindo García, Roberto Abdelkader Martínez Pérez 10 | 11 | This program is free software: you can redistribute it and/or modify 12 | it under the terms of the GNU Lesser General Public License as published by 13 | the Free Software Foundation, either version 3 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU Lesser General Public License for more details. 20 | 21 | You should have received a copy of the GNU Lesser General Public License 22 | along with this program. If not, see . 23 | 24 | For any problems using the cpe package, or general questions and 25 | feedback about it, please contact: 26 | 27 | - Alejandro Galindo García: galindo.garcia.alejandro@gmail.com 28 | - Roberto Abdelkader Martínez Pérez: robertomartinezp@gmail.com 29 | """ 30 | 31 | from .cpecomp_logical import CPEComponentLogical 32 | 33 | 34 | class CPEComponentEmpty(CPEComponentLogical): 35 | """ 36 | Represents an empty component of CPE name, 37 | compatible with the components of all versions of CPE specification. 38 | 39 | For example, in version 1.1 of CPE specification, an empty component 40 | is version attribute in CPE name cpe:/microsft:windows::sp2. 41 | """ 42 | 43 | #################### 44 | # OBJECT METHODS # 45 | #################### 46 | 47 | def __eq__(self, other): 48 | """ 49 | Returns True if other (first element of operation) and 50 | self (second element of operation) are equal components, 51 | false otherwise. 52 | 53 | :param CPEComponent other: component to compare 54 | :returns: True if other == self, False otherwise 55 | :rtype: boolean 56 | """ 57 | 58 | from .cpecomp_anyvalue import CPEComponentAnyValue 59 | from .cpecomp_undefined import CPEComponentUndefined 60 | 61 | return (isinstance(other, CPEComponentEmpty) or 62 | isinstance(other, CPEComponentUndefined) or 63 | isinstance(other, CPEComponentAnyValue)) 64 | 65 | def __init__(self): 66 | """ 67 | Initializes the component. 68 | """ 69 | 70 | super(CPEComponentEmpty, self).__init__( 71 | CPEComponentLogical._VALUE_INT_EMPTY) 72 | 73 | def __str__(self): 74 | """ 75 | Returns a human-readable representation of CPE component. 76 | 77 | :returns: Representation of CPE component as string 78 | :rtype: string 79 | """ 80 | 81 | return "" 82 | 83 | 84 | if __name__ == "__main__": 85 | import doctest 86 | doctest.testmod() 87 | doctest.testfile('../tests/testfile_cpecomp_empty.txt') 88 | -------------------------------------------------------------------------------- /cpe/comp/cpecomp_logical.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | This file is part of cpe package. 6 | 7 | This module allows to store the value of the logical components 8 | of a CPE name and compare it with others. 9 | 10 | Copyright (C) 2013 Alejandro Galindo García, Roberto Abdelkader Martínez Pérez 11 | 12 | This program is free software: you can redistribute it and/or modify 13 | it under the terms of the GNU Lesser General Public License as published by 14 | the Free Software Foundation, either version 3 of the License, or 15 | (at your option) any later version. 16 | 17 | This program is distributed in the hope that it will be useful, 18 | but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | GNU Lesser General Public License for more details. 21 | 22 | You should have received a copy of the GNU Lesser General Public License 23 | along with this program. If not, see . 24 | 25 | For any problems using the cpe package, or general questions and 26 | feedback about it, please contact: 27 | 28 | - Alejandro Galindo García: galindo.garcia.alejandro@gmail.com 29 | - Roberto Abdelkader Martínez Pérez: robertomartinezp@gmail.com 30 | """ 31 | 32 | from .cpecomp import CPEComponent 33 | 34 | 35 | class CPEComponentLogical(CPEComponent): 36 | """ 37 | Represents a generic logical component of CPE name, 38 | compatible with the components of all versions of CPE specification. 39 | """ 40 | 41 | ############### 42 | # CONSTANTS # 43 | ############### 44 | 45 | # Logical values in integer format 46 | 47 | #: Value of an undefined component. For example, edition attribute in the 48 | #: CPE name cpe:/cisco::2345 of version 1.1 of CPE specification 49 | _VALUE_INT_UNDEFINED = -1 50 | 51 | #: Value of an empty component. For example, product attribute in the 52 | #: CPE name cpe:/cisco::2345 of version 1.1 of CPE specification 53 | _VALUE_INT_EMPTY = 0 54 | 55 | #: Value of a component "any value". For example, product attribute in the 56 | #: CPE name cpe:/h:cisco:*:2345 of version 2.3 of CPE specification 57 | _VALUE_INT_ANY = 1 58 | 59 | #: Value of a not applicable component. For example, product attribute in 60 | #: the CPE name cpe:/h:cisco:-:2345 of version 2.3 of CPE specification 61 | _VALUE_INT_NA = 2 62 | 63 | #################### 64 | # OBJECT METHODS # 65 | #################### 66 | 67 | def __contains__(self, item): 68 | """ 69 | Returns True if item is included in set of values of self. 70 | 71 | :param CPEComponent item: component to find in self 72 | :returns: True if item is included in set of self 73 | :rtype: boolean 74 | """ 75 | 76 | return True 77 | 78 | def __eq__(self, other): 79 | """ 80 | Returns True if other (first element of operation) and 81 | self (second element of operation) are equal components, 82 | false otherwise. 83 | 84 | :param CPEComponent other: component to compare 85 | :returns: True if other == self, False otherwise 86 | :rtype: boolean 87 | :exception: NotImplementedError - class method not implemented 88 | """ 89 | 90 | errmsg = "Class method not implemented. Use the method of some child class" 91 | raise NotImplementedError(errmsg) 92 | 93 | def __str__(self): 94 | """ 95 | Returns a human-readable representation of CPE component. 96 | 97 | :returns: Representation of CPE component as string 98 | :rtype: string 99 | :exception: NotImplementedError - class method not implemented 100 | """ 101 | 102 | errmsg = "Class method not implemented. Use the method of some child class" 103 | raise NotImplementedError(errmsg) 104 | 105 | if __name__ == "__main__": 106 | import doctest 107 | doctest.testmod() 108 | doctest.testfile('../tests/testfile_cpecomp_logical.txt') 109 | -------------------------------------------------------------------------------- /cpe/comp/cpecomp_notapplicable.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | This file is part of cpe package. 6 | 7 | This module allows to create a component of CPE name with a 8 | not applicable value. 9 | 10 | Copyright (C) 2013 Alejandro Galindo García, Roberto Abdelkader Martínez Pérez 11 | 12 | This program is free software: you can redistribute it and/or modify 13 | it under the terms of the GNU Lesser General Public License as published by 14 | the Free Software Foundation, either version 3 of the License, or 15 | (at your option) any later version. 16 | 17 | This program is distributed in the hope that it will be useful, 18 | but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | GNU Lesser General Public License for more details. 21 | 22 | You should have received a copy of the GNU Lesser General Public License 23 | along with this program. If not, see . 24 | 25 | For any problems using the cpe package, or general questions and 26 | feedback about it, please contact: 27 | 28 | - Alejandro Galindo García: galindo.garcia.alejandro@gmail.com 29 | - Roberto Abdelkader Martínez Pérez: robertomartinezp@gmail.com 30 | """ 31 | 32 | from .cpecomp_logical import CPEComponentLogical 33 | 34 | 35 | class CPEComponentNotApplicable(CPEComponentLogical): 36 | """ 37 | Represents a component of CPE name with a not applicable value, 38 | compatible with the components of all versions of CPE specification. 39 | 40 | For example, in version 2.3 of CPE specification, an component "not 41 | applicable" is update attribute in CPE name cpe:/a:microsft:windows:me:-. 42 | """ 43 | 44 | #################### 45 | # OBJECT METHODS # 46 | #################### 47 | 48 | def __contains__(self, item): 49 | """ 50 | Returns True if item is included in set of values of self. 51 | 52 | :param CPEComponent item: component to find in self 53 | :returns: True if item is included in set of self 54 | :rtype: boolean 55 | """ 56 | 57 | return (self == item) 58 | 59 | def __eq__(self, other): 60 | """ 61 | Returns True if other (first element of operation) and 62 | self (second element of operation) are equal components, 63 | false otherwise. 64 | 65 | :param CPEComponent other: component to compare 66 | :returns: True if other == self, False otherwise 67 | :rtype: boolean 68 | """ 69 | 70 | return isinstance(other, CPEComponentNotApplicable) 71 | 72 | def __init__(self): 73 | """ 74 | Initializes the component. 75 | """ 76 | 77 | super(CPEComponentNotApplicable, self).__init__( 78 | CPEComponentLogical._VALUE_INT_NA) 79 | 80 | def __str__(self): 81 | """ 82 | Returns a human-readable representation of CPE component. 83 | 84 | :returns: Representation of CPE component as string 85 | :rtype: string 86 | """ 87 | 88 | return "" 89 | 90 | if __name__ == "__main__": 91 | import doctest 92 | doctest.testmod() 93 | doctest.testfile('../tests/testfile_cpecomp_notapplicable.txt') 94 | -------------------------------------------------------------------------------- /cpe/comp/cpecomp_undefined.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | This file is part of cpe package. 6 | 7 | This module allows to create an undefined component of CPE name. 8 | 9 | Copyright (C) 2013 Alejandro Galindo García, Roberto Abdelkader Martínez Pérez 10 | 11 | This program is free software: you can redistribute it and/or modify 12 | it under the terms of the GNU Lesser General Public License as published by 13 | the Free Software Foundation, either version 3 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU Lesser General Public License for more details. 20 | 21 | You should have received a copy of the GNU Lesser General Public License 22 | along with this program. If not, see . 23 | 24 | - Alejandro Galindo García: galindo.garcia.alejandro@gmail.com 25 | - Roberto Abdelkader Martínez Pérez: robertomartinezp@gmail.com 26 | """ 27 | 28 | from .cpecomp_logical import CPEComponentLogical 29 | 30 | 31 | class CPEComponentUndefined(CPEComponentLogical): 32 | """ 33 | Represents an undefined component of CPE name, 34 | compatible with the components of all versions of CPE specification. 35 | 36 | For example, in version 1.1 of CPE specification, an undefined component 37 | is edition attribute in CPE name cpe:/microsft:windows:xp. 38 | """ 39 | 40 | #################### 41 | # OBJECT METHODS # 42 | #################### 43 | 44 | def __contains__(self, item): 45 | """ 46 | Returns True if item is included in set of values of self. 47 | 48 | :param CPEComponent item: component to find in self 49 | :returns: True if item is included in set of self 50 | :rtype: boolean 51 | """ 52 | 53 | return super(CPEComponentUndefined, self).__contains__(item) 54 | 55 | def __eq__(self, other): 56 | """ 57 | Returns True if other (first element of operation) and 58 | self (second element of operation) are equal components, 59 | false otherwise. 60 | 61 | :param CPEComponent other: component to compare 62 | :returns: True if other == self, False otherwise 63 | """ 64 | 65 | from .cpecomp_anyvalue import CPEComponentAnyValue 66 | from .cpecomp_empty import CPEComponentEmpty 67 | 68 | return (isinstance(other, CPEComponentUndefined) or 69 | isinstance(other, CPEComponentEmpty) or 70 | isinstance(other, CPEComponentAnyValue)) 71 | 72 | def __init__(self): 73 | """ 74 | Initializes the component. 75 | """ 76 | 77 | super(CPEComponentUndefined, self).__init__( 78 | CPEComponentLogical._VALUE_INT_UNDEFINED) 79 | 80 | def __str__(self): 81 | """ 82 | Returns a human-readable representation of CPE component. 83 | 84 | :returns: Representation of CPE component as string 85 | :rtype: string 86 | """ 87 | 88 | return "" 89 | 90 | if __name__ == "__main__": 91 | import doctest 92 | doctest.testmod() 93 | doctest.testfile('../tests/testfile_cpecomp_undefined.txt') 94 | -------------------------------------------------------------------------------- /cpe/cpe2_3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | This file is part of cpe package. 6 | 7 | This module is used to the treatment of identifiers 8 | of IT platforms (hardware, operating systems or applications of system) 9 | in accordance with version 2.3 of CPE (Common Platform Enumeration) 10 | specification. 11 | 12 | Copyright (C) 2013 Alejandro Galindo García, Roberto Abdelkader Martínez Pérez 13 | 14 | This program is free software: you can redistribute it and/or modify 15 | it under the terms of the GNU Lesser General Public License as published by 16 | the Free Software Foundation, either version 3 of the License, or 17 | (at your option) any later version. 18 | 19 | This program is distributed in the hope that it will be useful, 20 | but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | GNU Lesser General Public License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public License 25 | along with this program. If not, see . 26 | 27 | For any problems using the cpe package, or general questions and 28 | feedback about it, please contact: 29 | 30 | - Alejandro Galindo García: galindo.garcia.alejandro@gmail.com 31 | - Roberto Abdelkader Martínez Pérez: robertomartinezp@gmail.com 32 | """ 33 | 34 | from .cpe import CPE 35 | 36 | 37 | class CPE2_3(CPE): 38 | """ 39 | Represents a generic CPE name compatible with 40 | all CPE name style of version 2.3 of CPE specification. 41 | """ 42 | 43 | ############### 44 | # CONSTANTS # 45 | ############### 46 | 47 | # Constants of possible CPE name styles of 2.3 version 48 | 49 | #: Formatted string style of version 2.3 of CPE specification 50 | STYLE_FS = "FS" 51 | 52 | #: Uniform Resource Identifier(URI) style of version 2.3 53 | #: of CPE specification 54 | STYLE_URI = "URI" 55 | 56 | #: Well-Formed Name (WFN) style of version 2.3 of CPE specification 57 | STYLE_WFN = "WFN" 58 | 59 | #: Style of version 2.3 of CPE specification not set 60 | STYLE_UNDEFINED = "undefined" 61 | 62 | #: Version of CPE name 63 | VERSION = CPE.VERSION_2_3 64 | 65 | #: Style of CPE name 66 | STYLE = STYLE_UNDEFINED 67 | 68 | #################### 69 | # OBJECT METHODS # 70 | #################### 71 | 72 | def __new__(cls, cpe_str, *args, **kwargs): 73 | """ 74 | Generator of CPE Names according to version 2.3. 75 | 76 | :param string cpe_str: CPE Name string 77 | :returns: CPE object of version 2.3 with style 78 | detected correctly 79 | :rtype: CPE2_3 80 | :exception: NotImplementedError - incorrect CPE Name or 81 | version of CPE not implemented 82 | 83 | This class implements the factory pattern, that is, 84 | this class centralizes the creation of objects of a particular 85 | CPE style of version 2.3, hiding the user the requested 86 | object instance. 87 | """ 88 | 89 | from .cpe2_3_fs import CPE2_3_FS 90 | from .cpe2_3_uri import CPE2_3_URI 91 | from .cpe2_3_wfn import CPE2_3_WFN 92 | 93 | # List of implemented styles of version 2.3 of CPE names 94 | _CPE_STYLES = { 95 | CPE2_3.STYLE_FS: CPE2_3_FS, 96 | CPE2_3.STYLE_URI: CPE2_3_URI, 97 | CPE2_3.STYLE_WFN: CPE2_3_WFN} 98 | 99 | errmsg = 'Style of version 2.3 of CPE not implemented' 100 | 101 | # Detect CPE version of input CPE name 102 | for s in _CPE_STYLES: 103 | try: 104 | # Validate CPE name 105 | c = _CPE_STYLES[s](cpe_str) 106 | except ValueError: 107 | # Test another style 108 | continue 109 | else: 110 | # Style detected 111 | return c 112 | 113 | raise NotImplementedError(errmsg) 114 | 115 | def __str__(self): 116 | """ 117 | Returns a human-readable representation of CPE Name. 118 | 119 | :returns: Representation of CPE Name as string 120 | :rtype: string 121 | """ 122 | 123 | return "CPE v{0} ({1}): {2}".format(CPE2_3.VERSION, 124 | self.STYLE, 125 | self.cpe_str) 126 | 127 | if __name__ == "__main__": 128 | import doctest 129 | doctest.testmod() 130 | doctest.testfile('tests/testfile_cpe2_3.txt') 131 | -------------------------------------------------------------------------------- /cpe/cpelang.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | This file is part of cpe package. 6 | 7 | This module contains the common characteristics of 8 | any CPE language matching algorithm, associated with a version of 9 | Common Platform Enumeration (CPE) specification. 10 | 11 | Copyright (C) 2013 Alejandro Galindo García, Roberto Abdelkader Martínez Pérez 12 | 13 | This program is free software: you can redistribute it and/or modify 14 | it under the terms of the GNU Lesser General Public License as published by 15 | the Free Software Foundation, either version 3 of the License, or 16 | (at your option) any later version. 17 | 18 | This program is distributed in the hope that it will be useful, 19 | but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | GNU Lesser General Public License for more details. 22 | 23 | You should have received a copy of the GNU Lesser General Public License 24 | along with this program. If not, see . 25 | 26 | For any problems using the cpe package, or general questions and 27 | feedback about it, please contact: 28 | 29 | - Alejandro Galindo García: galindo.garcia.alejandro@gmail.com 30 | - Roberto Abdelkader Martínez Pérez: robertomartinezp@gmail.com 31 | """ 32 | 33 | from xml.dom import minidom 34 | 35 | 36 | class CPELanguage(object): 37 | """ 38 | Represents an expression in the CPE Language. 39 | 40 | This class allows match a CPE element against an expression 41 | in the CPE Language, that is, a XML document format for 42 | binding descriptive prose and diagnostic test to a CPE Name 43 | (CPE Description Format). 44 | """ 45 | 46 | #################### 47 | # OBJECT METHODS # 48 | #################### 49 | 50 | def __init__(self, expression, isFile=False): 51 | """ 52 | Create an object that contains the input expression in 53 | the CPE Language (a set of CPE Names) and 54 | the DOM tree asociated with expression. 55 | 56 | :param string expression: XML content in string or a path to XML file 57 | :param strint isFile: indicates whether expression is a XML file or 58 | XML content string 59 | :returns: None 60 | """ 61 | 62 | if isFile: 63 | self.expression = "" 64 | self.path = expression 65 | 66 | # Parse an XML file by name (filepath) 67 | self.document = minidom.parse(self.path) 68 | else: 69 | self.expression = expression 70 | self.path = "" 71 | 72 | # Parse an XML stored in a string 73 | self.document = minidom.parseString(self.expression) 74 | 75 | def __str__(self): 76 | """ 77 | Returns a human-readable representation of CPE Language expression. 78 | 79 | :returns: Representation of CPE Language expression as string 80 | :rtype: string 81 | """ 82 | 83 | return "Expression of CPE language version {0}:\n{1}".format( 84 | self.VERSION, self.expression) 85 | 86 | def language_match(self, cpeset, cpel_dom=None): 87 | """ 88 | Accepts a set of known CPE Names and an expression in the CPE language, 89 | and delivers the answer True if the expression matches with the set. 90 | Otherwise, it returns False. 91 | 92 | :param CPELanguage self: An expression in the CPE Language, 93 | represented as the XML infoset for the platform element. 94 | :param CPESet cpeset: CPE set object to match with self expression. 95 | :param string cpel_dom: An expression in the CPE Language, 96 | represented as DOM tree. 97 | :returns: True if self expression can be satisfied by language matching 98 | against cpeset, False otherwise. 99 | :rtype: boolean 100 | :exception: NotImplementedError - Method not implemented 101 | """ 102 | 103 | errmsg = "Method not implemented. Use the method of some child class" 104 | raise NotImplementedError(errmsg) 105 | -------------------------------------------------------------------------------- /cpe/cpelang2_2.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | This file is part of cpe package. 6 | 7 | This module is an implementation of CPE language matching 8 | algorithm in accordance with version 2.2 of CPE (Common Platform 9 | Enumeration) specification. 10 | 11 | Copyright (C) 2013 Alejandro Galindo García, Roberto Abdelkader Martínez Pérez 12 | 13 | 14 | This program is free software: you can redistribute it and/or modify 15 | it under the terms of the GNU Lesser General Public License as published by 16 | the Free Software Foundation, either version 3 of the License, or 17 | (at your option) any later version. 18 | 19 | This program is distributed in the hope that it will be useful, 20 | but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | GNU Lesser General Public License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public License 25 | along with this program. If not, see . 26 | 27 | For any problems using the cpe package, or general questions and 28 | feedback about it, please contact: 29 | 30 | - Alejandro Galindo García: galindo.garcia.alejandro@gmail.com 31 | - Roberto Abdelkader Martínez Pérez: robertomartinezp@gmail.com 32 | """ 33 | 34 | from .cpe2_2 import CPE2_2 35 | from .cpelang import CPELanguage 36 | 37 | 38 | class CPELanguage2_2(CPELanguage): 39 | """ 40 | Represents an expression in the CPE Language. 41 | 42 | This class allows match a CPE element against an expression 43 | in the CPE Language, that is, a XML document format for 44 | binding descriptive prose and diagnostic test to a CPE name 45 | (CPE Description Format). 46 | """ 47 | 48 | ############### 49 | # CONSTANTS # 50 | ############### 51 | 52 | #: Version of CPE Language 53 | VERSION = "2.2" 54 | 55 | #################### 56 | # OBJECT METHODS # 57 | #################### 58 | 59 | def language_match(self, cpeset, cpel_dom=None): 60 | """ 61 | Accepts a set of known CPE Names and an expression in the CPE language, 62 | and delivers the answer True if the expression matches with the set. 63 | Otherwise, it returns False. 64 | 65 | :param CPELanguage self: An expression in the CPE Applicability 66 | Language, represented as the XML infoset for the platform element. 67 | :param CPESet cpeset: CPE set object to match with self expression. 68 | :param string cpel_dom: An expression in the CPE Applicability 69 | Language, represented as DOM tree. 70 | :returns: True if self expression can be satisfied by language matching 71 | against cpeset, False otherwise. 72 | :rtype: boolean 73 | """ 74 | 75 | # Root element tag 76 | TAG_ROOT = '#document' 77 | # A container for child platform definitions 78 | TAG_PLATSPEC = 'cpe:platform-specification' 79 | 80 | # Information about a platform definition 81 | TAG_PLATFORM = 'cpe:platform' 82 | TAG_LOGITEST = 'cpe:logical-test' 83 | TAG_CPE = 'cpe:fact-ref' 84 | 85 | # Tag attributes 86 | ATT_NAME = 'name' 87 | ATT_OP = 'operator' 88 | ATT_NEGATE = 'negate' 89 | 90 | # Attribute values 91 | ATT_OP_AND = 'AND' 92 | ATT_OP_OR = 'OR' 93 | ATT_NEGATE_TRUE = 'TRUE' 94 | 95 | if cpel_dom is None: 96 | cpel_dom = self.document 97 | 98 | # Identify the root element 99 | if cpel_dom.nodeName == TAG_ROOT or cpel_dom.nodeName == TAG_PLATSPEC: 100 | for node in cpel_dom.childNodes: 101 | if node.nodeName == TAG_PLATSPEC: 102 | return self.language_match(cpeset, node) 103 | if node.nodeName == TAG_PLATFORM: 104 | return self.language_match(cpeset, node) 105 | 106 | # Identify a platform element 107 | elif cpel_dom.nodeName == TAG_PLATFORM: 108 | for node in cpel_dom.childNodes: 109 | if node.nodeName == TAG_LOGITEST: 110 | return self.language_match(cpeset, node) 111 | 112 | # Identify a CPE element 113 | elif cpel_dom.nodeName == TAG_CPE: 114 | cpename = cpel_dom.getAttribute(ATT_NAME) 115 | c = CPE2_2(cpename) 116 | 117 | # Try to match a CPE name with CPE set 118 | return cpeset.name_match(c) 119 | 120 | # Identify a logical operator element 121 | elif cpel_dom.nodeName == TAG_LOGITEST: 122 | count = 0 123 | len = 0 124 | answer = False 125 | 126 | for node in cpel_dom.childNodes: 127 | if node.nodeName.find("#") == 0: 128 | continue 129 | len = len + 1 130 | if self.language_match(cpeset, node): 131 | count = count + 1 132 | 133 | operator = cpel_dom.getAttribute(ATT_OP).upper() 134 | 135 | if operator == ATT_OP_AND: 136 | if count == len: 137 | answer = True 138 | elif operator == ATT_OP_OR: 139 | if count > 0: 140 | answer = True 141 | 142 | operator_not = cpel_dom.getAttribute(ATT_NEGATE) 143 | if operator_not: 144 | if operator_not.upper() == ATT_NEGATE_TRUE: 145 | answer = not answer 146 | 147 | return answer 148 | else: 149 | return False 150 | 151 | if __name__ == "__main__": 152 | import doctest 153 | doctest.testmod() 154 | doctest.testfile("tests/testfile_cpelang2_2.txt") 155 | -------------------------------------------------------------------------------- /cpe/cpeset.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | This file is part of cpe package. 6 | 7 | This module contains the common characteristics of 8 | any name matching algorithm, associated with a version of Common Platform 9 | Enumeration (CPE) specification. 10 | 11 | Copyright (C) 2013 Alejandro Galindo García, Roberto Abdelkader Martínez Pérez 12 | 13 | This program is free software: you can redistribute it and/or modify 14 | it under the terms of the GNU Lesser General Public License as published by 15 | the Free Software Foundation, either version 3 of the License, or 16 | (at your option) any later version. 17 | 18 | This program is distributed in the hope that it will be useful, 19 | but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | GNU Lesser General Public License for more details. 22 | 23 | You should have received a copy of the GNU Lesser General Public License 24 | along with this program. If not, see . 25 | 26 | For any problems using the cpe package, or general questions and 27 | feedback about it, please contact: 28 | 29 | - Alejandro Galindo García: galindo.garcia.alejandro@gmail.com 30 | - Roberto Abdelkader Martínez Pérez: robertomartinezp@gmail.com 31 | """ 32 | 33 | from .cpe import CPE 34 | from .comp.cpecomp import CPEComponent 35 | 36 | 37 | class CPESet(object): 38 | """ 39 | Represents a set of CPE Names. 40 | 41 | This class allows: 42 | 43 | - create a set of CPE Names. 44 | - match a CPE Name against a set of CPE Names. 45 | """ 46 | 47 | #################### 48 | # OBJECT METHODS # 49 | #################### 50 | 51 | def __getitem__(self, i): 52 | """ 53 | Returns the i'th CPE Name of set. 54 | 55 | :param int i: CPE Name index to find 56 | :returns: CPE Name found 57 | :rtype: CPE 58 | :exception: IndexError - list index out of range 59 | """ 60 | 61 | return self.K[i] 62 | 63 | def __init__(self): 64 | """ 65 | Creates an empty set of CPE Names. 66 | 67 | :returns: None 68 | """ 69 | self.K = [] 70 | 71 | def __len__(self): 72 | """ 73 | Returns the count of CPE Names of set. 74 | 75 | :returns: count of components of CPE Name 76 | :rtype: int 77 | 78 | TEST: empty set 79 | 80 | >>> from .cpeset1_1 import CPESet1_1 81 | >>> s = CPESet1_1() 82 | >>> len(s) 83 | 0 84 | """ 85 | 86 | return len(self.K) 87 | 88 | def __str__(self): 89 | """ 90 | Returns a human-readable representation of CPE set. 91 | 92 | :returns: Representation of CPE set as string 93 | :rtype: string 94 | """ 95 | 96 | setlen = self.__len__() 97 | 98 | str = [] 99 | str.append("CPE Set version {0} contains {1} elements".format( 100 | self.VERSION, setlen)) 101 | if setlen > 0: 102 | str.append(":") 103 | 104 | for i in range(0, setlen): 105 | str.append(" {0}".format(self.K[i].__str__())) 106 | 107 | return "\n".join(str) 108 | 109 | def append(self, cpe): 110 | """ 111 | Adds a CPE Name to the set if not already. 112 | 113 | :param CPE cpe: CPE Name to store in set 114 | :returns: None 115 | :exception: NotImplementedError - Method not implemented 116 | """ 117 | 118 | errmsg = "Method not implemented. Use the method of some child class" 119 | raise NotImplementedError(errmsg) 120 | 121 | def name_match(self, cpe): 122 | """ 123 | Accepts a set of known instances of CPE Names and a candidate CPE Name, 124 | and returns 'True' if the candidate can be shown to be 125 | an instance based on the content of the known instances. 126 | Otherwise, it returns 'False'. 127 | 128 | :param CPESet self: A set of m known CPE Names K = {K1, K2, …, Km}. 129 | :param CPE cpe: A candidate CPE Name X. 130 | :returns: True if X matches K, otherwise False. 131 | :rtype: boolean 132 | """ 133 | 134 | # An empty set not matching with any CPE 135 | if len(self) == 0: 136 | return False 137 | 138 | # If input CPE Name string is in set of CPE Name strings 139 | # not do searching more because there is a matching 140 | for k in self.K: 141 | if (k.cpe_str == cpe.cpe_str): 142 | return True 143 | 144 | # If "cpe" is an empty CPE Name any system matches 145 | if len(cpe) == 0: 146 | return True 147 | 148 | # There are not a CPE Name string in set equal to 149 | # input CPE Name string 150 | match = False 151 | 152 | for p in CPE.CPE_PART_KEYS: 153 | elems_cpe = cpe.get(p) 154 | for ec in elems_cpe: 155 | # Search of element of part of input CPE 156 | 157 | # Each element ec of input cpe[p] is compared with 158 | # each element ek of k[p] in set K 159 | 160 | for k in self.K: 161 | if (len(k) >= len(cpe)): 162 | elems_k = k.get(p) 163 | 164 | for ek in elems_k: 165 | # Matching 166 | 167 | # Each component in element ec is compared with 168 | # each component in element ek 169 | for c in range(0, len(cpe)): 170 | key = CPEComponent.ordered_comp_parts[c] 171 | comp_cpe = ec.get(key) 172 | comp_k = ek.get(key) 173 | match = comp_k in comp_cpe 174 | 175 | if not match: 176 | # Search compoment in another element ek[p] 177 | break 178 | 179 | # Component analyzed 180 | 181 | if match: 182 | # Element matched 183 | break 184 | if match: 185 | break 186 | # Next element in part in "cpe" 187 | 188 | if not match: 189 | # cpe part not match with parts in set 190 | return False 191 | 192 | # Next part in input CPE Name 193 | 194 | # All parts in input CPE Name matched 195 | return True 196 | -------------------------------------------------------------------------------- /cpe/cpeset1_1.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | This file is part of cpe package. 6 | 7 | This module is an implementation of name matching 8 | algorithm in accordance with version 1.1 of CPE (Common Platform 9 | Enumeration) specification. 10 | 11 | Copyright (C) 2013 Roberto A. Martínez, Alejandro Galindo 12 | 13 | This program is free software: you can redistribute it and/or modify 14 | it under the terms of the GNU Lesser General Public License as published by 15 | the Free Software Foundation, either version 3 of the License, or 16 | (at your option) any later version. 17 | 18 | This program is distributed in the hope that it will be useful, 19 | but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | GNU Lesser General Public License for more details. 22 | 23 | You should have received a copy of the GNU Lesser General Public License 24 | along with this program. If not, see . 25 | 26 | For any problems using the cpe package, or general questions and 27 | feedback about it, please contact: galindo.garcia.alejandro@gmail.com. 28 | """ 29 | 30 | from .cpe import CPE 31 | from .comp.cpecomp import CPEComponent 32 | from .cpeset import CPESet 33 | 34 | 35 | class CPESet1_1(CPESet): 36 | """ 37 | Represents a set of CPE Names. 38 | 39 | This class allows: 40 | 41 | - create set of CPE Names. 42 | - match a CPE element against a set of CPE Names. 43 | """ 44 | 45 | ############### 46 | # CONSTANTS # 47 | ############### 48 | 49 | #: Version of CPE set 50 | VERSION = "1.1" 51 | 52 | #################### 53 | # OBJECT METHODS # 54 | #################### 55 | 56 | def append(self, cpe): 57 | """ 58 | Adds a CPE Name to the set if not already. 59 | 60 | :param CPE cpe: CPE Name to store in set 61 | :returns: None 62 | :exception: ValueError - invalid version of CPE Name 63 | 64 | TEST: 65 | 66 | >>> from .cpeset1_1 import CPESet1_1 67 | >>> from .cpe1_1 import CPE1_1 68 | >>> uri1 = 'cpe://microsoft:windows:xp!vista' 69 | >>> c1 = CPE1_1(uri1) 70 | >>> s = CPESet1_1() 71 | >>> s.append(c1) 72 | """ 73 | 74 | if cpe.VERSION != CPE.VERSION_1_1: 75 | msg = "CPE Name version {0} not valid, version 1.1 expected".format( 76 | cpe.VERSION) 77 | raise ValueError(msg) 78 | 79 | for k in self.K: 80 | if cpe.cpe_str == k.cpe_str: 81 | return None 82 | 83 | self.K.append(cpe) 84 | 85 | def name_match(self, cpe): 86 | """ 87 | Accepts a set of known instances of CPE Names and a candidate CPE Name, 88 | and returns 'True' if the candidate can be shown to be 89 | an instance based on the content of the known instances. 90 | Otherwise, it returns 'False'. 91 | 92 | :param CPESet self: A set of m known CPE Names K = {K1, K2, …, Km}. 93 | :param CPE cpe: A candidate CPE Name X. 94 | :returns: True if X matches K, otherwise False. 95 | :rtype: boolean 96 | 97 | TEST: matching with identical CPE in set 98 | 99 | >>> from .cpe1_1 import CPE1_1 100 | >>> from .cpeset1_1 import CPESet1_1 101 | >>> uri1 = 'cpe://microsoft:windows:xp!vista' 102 | >>> uri2 = 'cpe:/cisco::3825;cisco:2:44/cisco:ios:12.3:enterprise' 103 | >>> c1 = CPE1_1(uri1) 104 | >>> c2 = CPE1_1(uri2) 105 | >>> s = CPESet1_1() 106 | >>> s.append(c1) 107 | >>> s.append(c2) 108 | >>> s.name_match(c2) 109 | True 110 | 111 | """ 112 | 113 | # An empty set not matching with any CPE 114 | if len(self) == 0: 115 | return False 116 | 117 | # If input CPE Name string is in set of CPE Name strings 118 | # not do searching more because there is a matching 119 | for k in self.K: 120 | if (k.cpe_str == cpe.cpe_str): 121 | return True 122 | 123 | # There are not a CPE Name string in set equal to 124 | # input CPE Name string 125 | match = False 126 | 127 | for p in CPE.CPE_PART_KEYS: 128 | elems_cpe = cpe.get(p) 129 | for ec in elems_cpe: 130 | # Search of element of part of input CPE 131 | 132 | # Each element ec of input cpe[p] is compared with 133 | # each element ek of k[p] in set K 134 | 135 | for k in self.K: 136 | elems_k = k.get(p) 137 | 138 | for ek in elems_k: 139 | # Matching 140 | 141 | # Each component in element ec is compared with 142 | # each component in element ek 143 | for ck in CPEComponent.CPE_COMP_KEYS: 144 | comp_cpe = ec.get(ck) 145 | comp_k = ek.get(ck) 146 | 147 | match = comp_k in comp_cpe 148 | 149 | if not match: 150 | # Search compoment in another element ek[p] 151 | break 152 | 153 | # Component analyzed 154 | 155 | if match: 156 | # Element matched 157 | break 158 | if match: 159 | break 160 | # Next element in part in "cpe" 161 | 162 | if not match: 163 | # cpe part not match with parts in set 164 | return False 165 | 166 | # Next part in input CPE Name 167 | 168 | # All parts in input CPE Name matched 169 | return True 170 | 171 | if __name__ == "__main__": 172 | import doctest 173 | doctest.testmod() 174 | doctest.testfile("tests/testfile_cpeset1_1.txt") 175 | -------------------------------------------------------------------------------- /cpe/cpeset2_2.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | This file is part of cpe package. 6 | 7 | This module of is an implementation of name matching 8 | algorithm in accordance with version 2.2 of CPE (Common Platform 9 | Enumeration) specification. 10 | 11 | Copyright (C) 2013 Alejandro Galindo García, Roberto Abdelkader Martínez Pérez 12 | 13 | This program is free software: you can redistribute it and/or modify 14 | it under the terms of the GNU Lesser General Public License as published by 15 | the Free Software Foundation, either version 3 of the License, or 16 | (at your option) any later version. 17 | 18 | This program is distributed in the hope that it will be useful, 19 | but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | GNU Lesser General Public License for more details. 22 | 23 | You should have received a copy of the GNU Lesser General Public License 24 | along with this program. If not, see . 25 | 26 | For any problems using the cpe package, or general questions and 27 | feedback about it, please contact: 28 | 29 | - Alejandro Galindo García: galindo.garcia.alejandro@gmail.com 30 | - Roberto Abdelkader Martínez Pérez: robertomartinezp@gmail.com 31 | """ 32 | 33 | from .cpe import CPE 34 | from .cpeset import CPESet 35 | 36 | 37 | class CPESet2_2(CPESet): 38 | """ 39 | Represents a set of CPE Names. 40 | 41 | This class allows: 42 | 43 | - create set of CPE Names. 44 | - match a CPE element against a set of CPE Names. 45 | """ 46 | 47 | ############### 48 | # CONSTANTS # 49 | ############### 50 | 51 | #: Version of CPE set 52 | VERSION = "2.2" 53 | 54 | #################### 55 | # OBJECT METHODS # 56 | #################### 57 | 58 | def append(self, cpe): 59 | """ 60 | Adds a CPE Name to the set if not already. 61 | 62 | :param CPE cpe: CPE Name to store in set 63 | :returns: None 64 | :exception: ValueError - invalid version of CPE Name 65 | 66 | 67 | TEST: 68 | 69 | >>> from .cpeset2_2 import CPESet2_2 70 | >>> from .cpe2_2 import CPE2_2 71 | >>> uri1 = 'cpe:/h:hp' 72 | >>> c1 = CPE2_2(uri1) 73 | >>> s = CPESet2_2() 74 | >>> s.append(c1) 75 | """ 76 | 77 | if cpe.VERSION != CPE.VERSION_2_2: 78 | errmsg = "CPE Name version {0} not valid, version 2.2 expected".format( 79 | cpe.VERSION) 80 | raise ValueError(errmsg) 81 | 82 | for k in self.K: 83 | if cpe.cpe_str == k.cpe_str: 84 | return None 85 | 86 | self.K.append(cpe) 87 | 88 | def name_match(self, cpe): 89 | """ 90 | Accepts a set of known instances of CPE Names and a candidate CPE Name, 91 | and returns 'True' if the candidate can be shown to be 92 | an instance based on the content of the known instances. 93 | Otherwise, it returns 'False'. 94 | 95 | :param CPESet self: A set of m known CPE Names K = {K1, K2, …, Km}. 96 | :param CPE cpe: A candidate CPE Name X. 97 | :returns: True if X matches K, otherwise False. 98 | :rtype: boolean 99 | 100 | TEST: matching with ANY values explicit 101 | 102 | >>> from .cpe2_2 import CPE2_2 103 | >>> uri1 = 'cpe:/o:microsoft:windows:vista' 104 | >>> uri2 = 'cpe:/o:cisco:ios:12.3:enterprise' 105 | >>> c1 = CPE2_2(uri1) 106 | >>> c2 = CPE2_2(uri2) 107 | >>> s = CPESet2_2() 108 | >>> s.append(c1) 109 | >>> s.append(c2) 110 | >>> uri3 = 'cpe:/o:microsoft::vista' 111 | >>> c3 = CPE2_2(uri3) 112 | >>> s.name_match(c3) 113 | True 114 | """ 115 | 116 | return super(CPESet2_2, self).name_match(cpe) 117 | 118 | if __name__ == "__main__": 119 | import doctest 120 | doctest.testmod() 121 | doctest.testfile("tests/testfile_cpeset2_2.txt") 122 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # User-friendly check for sphinx-build 11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) 12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) 13 | endif 14 | 15 | # Internal variables. 16 | PAPEROPT_a4 = -D latex_paper_size=a4 17 | PAPEROPT_letter = -D latex_paper_size=letter 18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 19 | # the i18n builder cannot share the environment and doctrees with the others 20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 21 | 22 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext 23 | 24 | help: 25 | @echo "Please use \`make ' where is one of" 26 | @echo " html to make standalone HTML files" 27 | @echo " dirhtml to make HTML files named index.html in directories" 28 | @echo " singlehtml to make a single large HTML file" 29 | @echo " pickle to make pickle files" 30 | @echo " json to make JSON files" 31 | @echo " htmlhelp to make HTML files and a HTML help project" 32 | @echo " qthelp to make HTML files and a qthelp project" 33 | @echo " devhelp to make HTML files and a Devhelp project" 34 | @echo " epub to make an epub" 35 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 36 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 37 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 38 | @echo " text to make text files" 39 | @echo " man to make manual pages" 40 | @echo " texinfo to make Texinfo files" 41 | @echo " info to make Texinfo files and run them through makeinfo" 42 | @echo " gettext to make PO message catalogs" 43 | @echo " changes to make an overview of all changed/added/deprecated items" 44 | @echo " xml to make Docutils-native XML files" 45 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 46 | @echo " linkcheck to check all external links for integrity" 47 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 48 | 49 | clean: 50 | rm -rf $(BUILDDIR)/* 51 | 52 | html: 53 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 54 | @echo 55 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 56 | 57 | dirhtml: 58 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 59 | @echo 60 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 61 | 62 | singlehtml: 63 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 64 | @echo 65 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 66 | 67 | pickle: 68 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 69 | @echo 70 | @echo "Build finished; now you can process the pickle files." 71 | 72 | json: 73 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 74 | @echo 75 | @echo "Build finished; now you can process the JSON files." 76 | 77 | htmlhelp: 78 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 79 | @echo 80 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 81 | ".hhp project file in $(BUILDDIR)/htmlhelp." 82 | 83 | qthelp: 84 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 85 | @echo 86 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 87 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 88 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/CPE.qhcp" 89 | @echo "To view the help file:" 90 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/CPE.qhc" 91 | 92 | devhelp: 93 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 94 | @echo 95 | @echo "Build finished." 96 | @echo "To view the help file:" 97 | @echo "# mkdir -p $$HOME/.local/share/devhelp/CPE" 98 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/CPE" 99 | @echo "# devhelp" 100 | 101 | epub: 102 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 103 | @echo 104 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 105 | 106 | latex: 107 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 108 | @echo 109 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 110 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 111 | "(use \`make latexpdf' here to do that automatically)." 112 | 113 | latexpdf: 114 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 115 | @echo "Running LaTeX files through pdflatex..." 116 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 117 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 118 | 119 | latexpdfja: 120 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 121 | @echo "Running LaTeX files through platex and dvipdfmx..." 122 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 123 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 124 | 125 | text: 126 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 127 | @echo 128 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 129 | 130 | man: 131 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 132 | @echo 133 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 134 | 135 | texinfo: 136 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 137 | @echo 138 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 139 | @echo "Run \`make' in that directory to run these through makeinfo" \ 140 | "(use \`make info' here to do that automatically)." 141 | 142 | info: 143 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 144 | @echo "Running Texinfo files through makeinfo..." 145 | make -C $(BUILDDIR)/texinfo info 146 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 147 | 148 | gettext: 149 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 150 | @echo 151 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 152 | 153 | changes: 154 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 155 | @echo 156 | @echo "The overview file is in $(BUILDDIR)/changes." 157 | 158 | linkcheck: 159 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 160 | @echo 161 | @echo "Link check complete; look for any errors in the above output " \ 162 | "or in $(BUILDDIR)/linkcheck/output.txt." 163 | 164 | doctest: 165 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 166 | @echo "Testing of doctests in the sources finished, look at the " \ 167 | "results in $(BUILDDIR)/doctest/output.txt." 168 | 169 | xml: 170 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 171 | @echo 172 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 173 | 174 | pseudoxml: 175 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 176 | @echo 177 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 178 | -------------------------------------------------------------------------------- /docs/_static/cpe/cpe_model_all.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilp0inter/cpe/50ba2ee28b5d6b24fa2c5b1493de9de953ca7dce/docs/_static/cpe/cpe_model_all.png -------------------------------------------------------------------------------- /docs/_static/cpe/cpe_model_all.pyns: -------------------------------------------------------------------------------- 1 | # PynSource Version 1.1 2 | {'type':'meta', 'info1':'Lorem ipsum dolor sit amet, consectetur adipiscing elit is latin.'} 3 | {'type':'umlshape', 'id':'CPE', 'x':15, 'y':84, 'width':210, 'height':797, 'attrs':'_PREFIX_ELEM|_PREFIX_ELEMENTS|_SUFFIX_ELEM|_SUFFIX_ELEMENTS|KEY_APP|KEY_HW|KEY_OS|KEY_UNDEFINED|CPE_PART_KEYS|VERSION_1_1|VERSION_2_2|VERSION_2_3|VERSION_UNDEFINED|VERSION|system_and_parts|cpe_str|_str', 'meths':'_trim|__eq__|__getitem__|__init__|__len__|__new__|__repr__|__str__|_create_cpe_parts|_get_attribute_components|_pack_edition|as_dict|as_uri_2_3|as_wfn|as_fs|get_edition|get_language|get_other|get_part|get_product|get_software_edition|get_target_hardware|get_target_software|get_update|get_vendor|get_version|is_application|is_hardware|is_operating_system'} 4 | {'type':'umlshape', 'id':'dict', 'x':83, 'y':25, 'width':54, 'height':31, 'attrs':'', 'meths':''} 5 | {'type':'umlshape', 'id':'CPE1_1', 'x':311, 'y':23, 'width':170, 'height':285, 'attrs':'PART_SEPARATOR|ELEMENT_SEPARATOR|VERSION|_hw|_os|_app|_parts_pattern|_parts_rxc', 'meths':'__getitem__|__len__|__new__|_parse|as_wfn|get_attribute_values'} 6 | {'type':'umlshape', 'id':'CPE2_2', 'x':311, 'y':332, 'width':170, 'height':301, 'attrs':'VERSION|_part|_vendor|_product|_version|_update|_edition|_language|_parts_pattern|_parts_rxc', 'meths':'__len__|__new__|_parse|as_wfn|get_attribute_values'} 7 | {'type':'umlshape', 'id':'CPE2_3', 'x':310, 'y':665, 'width':172, 'height':189, 'attrs':'STYLE_FS|STYLE_URI|STYLE_WFN|STYLE_UNDEFINED|VERSION|STYLE', 'meths':'__new__|__str__'} 8 | {'type':'umlshape', 'id':'CPE2_3_FS', 'x':575, 'y':863, 'width':170, 'height':365, 'attrs':'STYLE|_logical|_typesys|_vendor|_product|_version|_update|_edition|_language|_sw_edition|_target_sw|_target_hw|_other|_parts_pattern|_parts_rxc', 'meths':'__len__|__new__|_parse|get_attribute_values'} 9 | {'type':'umlshape', 'id':'CPE2_3_URI', 'x':575, 'y':311, 'width':170, 'height':349, 'attrs':'STYLE|_typesys|_vendor|_product|_version|_update|_edition|_language|_parts_pattern|_parts_rxc', 'meths':'_create_component|_unpack_edition|__getitem__|__len__|__new__|_parse|as_wfn|get_attribute_values'} 10 | {'type':'umlshape', 'id':'CPE2_3_WFN', 'x':575, 'y':682, 'width':170, 'height':157, 'attrs':'STYLE|CPE_PREFIX|CPE_SUFFIX', 'meths':'__new__|_parse|get_attribute_values'} 11 | {'type':'edge', 'id':'CPE_to_dict', 'source':'CPE', 'target':'dict', 'uml_edge_type':'generalisation'} 12 | {'type':'edge', 'id':'CPE1_1_to_CPE', 'source':'CPE1_1', 'target':'CPE', 'uml_edge_type':'generalisation'} 13 | {'type':'edge', 'id':'CPE2_2_to_CPE', 'source':'CPE2_2', 'target':'CPE', 'uml_edge_type':'generalisation'} 14 | {'type':'edge', 'id':'CPE2_3_to_CPE', 'source':'CPE2_3', 'target':'CPE', 'uml_edge_type':'generalisation'} 15 | {'type':'edge', 'id':'CPE2_3_FS_to_CPE2_3', 'source':'CPE2_3_FS', 'target':'CPE2_3', 'uml_edge_type':'generalisation'} 16 | {'type':'edge', 'id':'CPE2_3_URI_to_CPE2_3', 'source':'CPE2_3_URI', 'target':'CPE2_3', 'uml_edge_type':'generalisation'} 17 | {'type':'edge', 'id':'CPE2_3_WFN_to_CPE2_3', 'source':'CPE2_3_WFN', 'target':'CPE2_3', 'uml_edge_type':'generalisation'} 18 | -------------------------------------------------------------------------------- /docs/_static/cpe/cpe_model_all.pyns.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilp0inter/cpe/50ba2ee28b5d6b24fa2c5b1493de9de953ca7dce/docs/_static/cpe/cpe_model_all.pyns.pdf -------------------------------------------------------------------------------- /docs/_static/cpe/cpe_model_public.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilp0inter/cpe/50ba2ee28b5d6b24fa2c5b1493de9de953ca7dce/docs/_static/cpe/cpe_model_public.png -------------------------------------------------------------------------------- /docs/_static/cpe/cpe_model_public.pyns: -------------------------------------------------------------------------------- 1 | # PynSource Version 1.1 2 | {'type':'meta', 'info1':'Lorem ipsum dolor sit amet, consectetur adipiscing elit is latin.'} 3 | {'type':'umlshape', 'id':'CPE', 'x':15, 'y':79, 'width':170, 'height':653, 'attrs':'KEY_APP|KEY_HW|KEY_OS|KEY_UNDEFINED|CPE_PART_KEYS|VERSION_1_1|VERSION_2_2|VERSION_2_3|VERSION_UNDEFINED|VERSION|system_and_parts|cpe_str', 'meths':'__eq__|__getitem__|__init__|__len__|__new__|__repr__|__str__|as_dict|as_uri_2_3|as_wfn|as_fs|get_edition|get_language|get_other|get_part|get_product|get_software_edition|get_target_hardware|get_target_software|get_update|get_vendor|get_version|is_application|is_hardware|is_operating_system'} 4 | {'type':'umlshape', 'id':'dict', 'x':78, 'y':25, 'width':54, 'height':31, 'attrs':'', 'meths':''} 5 | {'type':'umlshape', 'id':'CPE1_1', 'x':285, 'y':121, 'width':170, 'height':189, 'attrs':'PART_SEPARATOR|ELEMENT_SEPARATOR|VERSION', 'meths':'__getitem__|__len__|__new__|as_wfn|get_attribute_values'} 6 | {'type':'umlshape', 'id':'CPE2_2', 'x':285, 'y':335, 'width':170, 'height':141, 'attrs':'VERSION', 'meths':'__len__|__new__|as_wfn|get_attribute_values'} 7 | {'type':'umlshape', 'id':'CPE2_3', 'x':285, 'y':510, 'width':171, 'height':189, 'attrs':'STYLE_FS|STYLE_URI|STYLE_WFN|STYLE_UNDEFINED|VERSION|STYLE', 'meths':'__new__|__str__'} 8 | {'type':'umlshape', 'id':'CPE2_3_FS', 'x':545, 'y':698, 'width':170, 'height':125, 'attrs':'STYLE', 'meths':'__len__|__new__|get_attribute_values'} 9 | {'type':'umlshape', 'id':'CPE2_3_URI', 'x':540, 'y':356, 'width':178, 'height':157, 'attrs':'STYLE', 'meths':'__getitem__|__len__|__new__|as_wfn|get_attribute_values'} 10 | {'type':'umlshape', 'id':'CPE2_3_WFN', 'x':545, 'y':535, 'width':170, 'height':141, 'attrs':'STYLE|CPE_PREFIX|CPE_SUFFIX', 'meths':'__new__|get_attribute_values'} 11 | {'type':'edge', 'id':'CPE_to_dict', 'source':'CPE', 'target':'dict', 'uml_edge_type':'generalisation'} 12 | {'type':'edge', 'id':'CPE1_1_to_CPE', 'source':'CPE1_1', 'target':'CPE', 'uml_edge_type':'generalisation'} 13 | {'type':'edge', 'id':'CPE2_2_to_CPE', 'source':'CPE2_2', 'target':'CPE', 'uml_edge_type':'generalisation'} 14 | {'type':'edge', 'id':'CPE2_3_to_CPE', 'source':'CPE2_3', 'target':'CPE', 'uml_edge_type':'generalisation'} 15 | {'type':'edge', 'id':'CPE2_3_FS_to_CPE2_3', 'source':'CPE2_3_FS', 'target':'CPE2_3', 'uml_edge_type':'generalisation'} 16 | {'type':'edge', 'id':'CPE2_3_URI_to_CPE2_3', 'source':'CPE2_3_URI', 'target':'CPE2_3', 'uml_edge_type':'generalisation'} 17 | {'type':'edge', 'id':'CPE2_3_WFN_to_CPE2_3', 'source':'CPE2_3_WFN', 'target':'CPE2_3', 'uml_edge_type':'generalisation'} 18 | -------------------------------------------------------------------------------- /docs/_static/cpe/cpe_model_public.pyns.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilp0inter/cpe/50ba2ee28b5d6b24fa2c5b1493de9de953ca7dce/docs/_static/cpe/cpe_model_public.pyns.pdf -------------------------------------------------------------------------------- /docs/_static/cpe_logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilp0inter/cpe/50ba2ee28b5d6b24fa2c5b1493de9de953ca7dce/docs/_static/cpe_logo.gif -------------------------------------------------------------------------------- /docs/_static/cpecomp/cpecomp_model_all.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilp0inter/cpe/50ba2ee28b5d6b24fa2c5b1493de9de953ca7dce/docs/_static/cpecomp/cpecomp_model_all.png -------------------------------------------------------------------------------- /docs/_static/cpecomp/cpecomp_model_all.pyns: -------------------------------------------------------------------------------- 1 | # PynSource Version 1.1 2 | {'type':'meta', 'info1':'Lorem ipsum dolor sit amet, consectetur adipiscing elit is latin.'} 3 | {'type':'umlshape', 'id':'CPEComponent', 'x':22, 'y':391, 'width':186, 'height':589, 'attrs':'COMP_1_1|COMP_2_2|COMP_2_3_WFN|COMP_2_3_URI|COMP_2_3_FS|ATT_PART|ATT_VENDOR|ATT_PRODUCT|ATT_VERSION|ATT_UPDATE|ATT_EDITION|ATT_LANGUAGE|ATT_SW_EDITION|ATT_TARGET_SW|ATT_TARGET_HW|ATT_OTHER|CPE_COMP_KEYS|CPE_COMP_KEYS_EXTENDED|VALUE_PART_HW|VALUE_PART_OS|VALUE_PART_APP|VALUE_PART_UNDEFINED|SYSTEM_VALUES|ordered_comp_parts|_is_negated|_encoded_value|_standard_value', 'meths':'is_valid_attribute|__contains__|__eq__|__init__|__ne__|__repr__'} 4 | {'type':'umlshape', 'id':'object', 'x':77, 'y':280, 'width':76, 'height':31, 'attrs':'', 'meths':''} 5 | {'type':'umlshape', 'id':'CPEComponentAnyValue', 'x':550, 'y':276, 'width':230, 'height':99, 'attrs':'', 'meths':'__eq__|__init__|__str__'} 6 | {'type':'umlshape', 'id':'CPEComponentLogical', 'x':252, 'y':255, 'width':219, 'height':31, 'attrs':'', 'meths':''} 7 | {'type':'umlshape', 'id':'CPEComponentEmpty', 'x':552, 'y':161, 'width':197, 'height':99, 'attrs':'', 'meths':'__eq__|__init__|__str__'} 8 | {'type':'umlshape', 'id':'CPEComponentNotApplicable', 'x':512, 'y':17, 'width':285, 'height':115, 'attrs':'', 'meths':'__contains__|__eq__|__init__|__str__'} 9 | {'type':'umlshape', 'id':'CPEComponentSimple', 'x':256, 'y':659, 'width':208, 'height':381, 'attrs':'_ALPHANUM_PATTERN|_LANGTAG_PATTERN|_PART_PATTERN|spechar_to_pce|_standard_value|_encoded_value', 'meths':'_is_alphanum|_pct_encode_uri|__init__|__str__|_is_valid_edition|_is_valid_language|_is_valid_part|_is_valid_value|_parse|as_fs|as_uri_2_3|as_wfn|get_value|set_value'} 10 | {'type':'umlshape', 'id':'CPEComponentUndefined', 'x':540, 'y':403, 'width':241, 'height':115, 'attrs':'', 'meths':'__contains__|__eq__|__init__|__str__'} 11 | {'type':'umlshape', 'id':'CPEComponent1_1', 'x':533, 'y':582, 'width':175, 'height':317, 'attrs':'_ESCAPE_SEPARATOR|_STRING|SEPARATOR_COMP|NON_STANDARD_VALUES|VALUE_UNDEFINED|VALUE_EMPTY|_standard_value|_is_negated', 'meths':'__contains__|__repr__|_decode|_is_valid_value|as_fs|as_uri_2_3|as_wfn|set_value'} 12 | {'type':'umlshape', 'id':'CPEComponent2_2', 'x':533, 'y':930, 'width':175, 'height':221, 'attrs':'_VALUE_PATTERN|SEPARATOR_COMP|NON_STANDARD_VALUES|VALUE_UNDEFINED|VALUE_EMPTY|_value_rxc|_standard_value', 'meths':'__repr__|_decode|_is_valid_value'} 13 | {'type':'umlshape', 'id':'CPEComponent2_3', 'x':533, 'y':1341, 'width':175, 'height':99, 'attrs':'', 'meths':'__repr__|_is_valid_language|_is_valid_part'} 14 | {'type':'umlshape', 'id':'CPEComponent2_3_FS', 'x':891, 'y':409, 'width':208, 'height':381, 'attrs':'_UNRESERVED|_PUNC|SEPARATOR_COMP|SEPARATOR_LANG|VALUE_ANY|VALUE_NA|WILDCARD_MULTI|WILDCARD_ONE|_logical|_quest|_asterisk|_special|_spec_chrs|_quoted|_avstring|_value_string_pattern|_part_value_rxc|_standard_value', 'meths':'_decode|_is_valid_value'} 15 | {'type':'umlshape', 'id':'CPEComponent2_3_URI', 'x':880, 'y':1340, 'width':219, 'height':429, 'attrs':'_PCT_ENCODED|_SPEC_CHRS|_UNRESERVED|SEPARATOR_COMP|SEPARATOR_LANG|SEPARATOR_PACKED_EDITION|VALUE_ANY|VALUE_NA|VALUE_EMPTY|VALUE_UNDEFINED|WILDCARD_MULTI|WILDCARD_ONE|_str_w_special|_str_wo_special|_string|_value_pattern|_value_rxc|char_to_pce|pce_char_to_decode|_standard_value', 'meths':'_decode|_is_valid_edition|_is_valid_value'} 16 | {'type':'umlshape', 'id':'CPEComponent2_3_URI_edpacked', 'x':1141, 'y':1452, 'width':318, 'height':205, 'attrs':'SEPARATOR_COMP|_is_negated|_encoded_value|_standard_value', 'meths':'__init__|_decode|_is_valid_edition|_is_valid_value|set_value'} 17 | {'type':'umlshape', 'id':'CPEComponent2_3_WFN', 'x':890, 'y':831, 'width':219, 'height':477, 'attrs':'_ESCAPE|_PUNC_NO_DASH|SEPARATOR_COMP|SEPARATOR_PAIR|SEPARATOR_LANG|VALUE_ANY|VALUE_NA|WILDCARD_MULTI|WILDCARD_ONE|_spec1|_spec2|_spec_chrs|_special|_punc_w_dash|_quoted1|_quoted2|_body1|_body2|_body|_avstring_pattern|_value_rxc|_standard_value', 'meths':'_decode|_is_valid_value|get_value|set_value'} 18 | {'type':'edge', 'id':'CPEComponent_to_object', 'source':'CPEComponent', 'target':'object', 'uml_edge_type':'generalisation'} 19 | {'type':'edge', 'id':'CPEComponentAnyValue_to_CPEComponentLogical', 'source':'CPEComponentAnyValue', 'target':'CPEComponentLogical', 'uml_edge_type':'generalisation'} 20 | {'type':'edge', 'id':'CPEComponentEmpty_to_CPEComponentLogical', 'source':'CPEComponentEmpty', 'target':'CPEComponentLogical', 'uml_edge_type':'generalisation'} 21 | {'type':'edge', 'id':'CPEComponentLogical_to_CPEComponent', 'source':'CPEComponentLogical', 'target':'CPEComponent', 'uml_edge_type':'generalisation'} 22 | {'type':'edge', 'id':'CPEComponentNotApplicable_to_CPEComponentLogical', 'source':'CPEComponentNotApplicable', 'target':'CPEComponentLogical', 'uml_edge_type':'generalisation'} 23 | {'type':'edge', 'id':'CPEComponentSimple_to_CPEComponent', 'source':'CPEComponentSimple', 'target':'CPEComponent', 'uml_edge_type':'generalisation'} 24 | {'type':'edge', 'id':'CPEComponentUndefined_to_CPEComponentLogical', 'source':'CPEComponentUndefined', 'target':'CPEComponentLogical', 'uml_edge_type':'generalisation'} 25 | {'type':'edge', 'id':'CPEComponent1_1_to_CPEComponentSimple', 'source':'CPEComponent1_1', 'target':'CPEComponentSimple', 'uml_edge_type':'generalisation'} 26 | {'type':'edge', 'id':'CPEComponent2_2_to_CPEComponentSimple', 'source':'CPEComponent2_2', 'target':'CPEComponentSimple', 'uml_edge_type':'generalisation'} 27 | {'type':'edge', 'id':'CPEComponent2_3_to_CPEComponentSimple', 'source':'CPEComponent2_3', 'target':'CPEComponentSimple', 'uml_edge_type':'generalisation'} 28 | {'type':'edge', 'id':'CPEComponent2_3_FS_to_CPEComponent2_3', 'source':'CPEComponent2_3_FS', 'target':'CPEComponent2_3', 'uml_edge_type':'generalisation'} 29 | {'type':'edge', 'id':'CPEComponent2_3_URI_to_CPEComponent2_3', 'source':'CPEComponent2_3_URI', 'target':'CPEComponent2_3', 'uml_edge_type':'generalisation'} 30 | {'type':'edge', 'id':'CPEComponent2_3_URI_edpacked_to_CPEComponent2_3_URI', 'source':'CPEComponent2_3_URI_edpacked', 'target':'CPEComponent2_3_URI', 'uml_edge_type':'generalisation'} 31 | {'type':'edge', 'id':'CPEComponent2_3_WFN_to_CPEComponent2_3', 'source':'CPEComponent2_3_WFN', 'target':'CPEComponent2_3', 'uml_edge_type':'generalisation'} 32 | -------------------------------------------------------------------------------- /docs/_static/cpecomp/cpecomp_model_all.pyns.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilp0inter/cpe/50ba2ee28b5d6b24fa2c5b1493de9de953ca7dce/docs/_static/cpecomp/cpecomp_model_all.pyns.pdf -------------------------------------------------------------------------------- /docs/_static/cpecomp/cpecomp_model_public.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilp0inter/cpe/50ba2ee28b5d6b24fa2c5b1493de9de953ca7dce/docs/_static/cpecomp/cpecomp_model_public.png -------------------------------------------------------------------------------- /docs/_static/cpecomp/cpecomp_model_public.pyns: -------------------------------------------------------------------------------- 1 | # PynSource Version 1.1 2 | {'type':'meta', 'info1':'Lorem ipsum dolor sit amet, consectetur adipiscing elit is latin.'} 3 | {'type':'umlshape', 'id':'CPEComponent', 'x':22, 'y':391, 'width':186, 'height':541, 'attrs':'COMP_1_1|COMP_2_2|COMP_2_3_WFN|COMP_2_3_URI|COMP_2_3_FS|ATT_PART|ATT_VENDOR|ATT_PRODUCT|ATT_VERSION|ATT_UPDATE|ATT_EDITION|ATT_LANGUAGE|ATT_SW_EDITION|ATT_TARGET_SW|ATT_TARGET_HW|ATT_OTHER|CPE_COMP_KEYS|CPE_COMP_KEYS_EXTENDED|VALUE_PART_HW|VALUE_PART_OS|VALUE_PART_APP|VALUE_PART_UNDEFINED|SYSTEM_VALUES|ordered_comp_parts', 'meths':'is_valid_attribute|__contains__|__eq__|__init__|__ne__|__repr__'} 4 | {'type':'umlshape', 'id':'object', 'x':77, 'y':280, 'width':76, 'height':31, 'attrs':'', 'meths':''} 5 | {'type':'umlshape', 'id':'CPEComponentAnyValue', 'x':550, 'y':276, 'width':230, 'height':99, 'attrs':'', 'meths':'__eq__|__init__|__str__'} 6 | {'type':'umlshape', 'id':'CPEComponentLogical', 'x':252, 'y':255, 'width':219, 'height':31, 'attrs':'', 'meths':''} 7 | {'type':'umlshape', 'id':'CPEComponentEmpty', 'x':552, 'y':161, 'width':197, 'height':99, 'attrs':'', 'meths':'__eq__|__init__|__str__'} 8 | {'type':'umlshape', 'id':'CPEComponentNotApplicable', 'x':512, 'y':17, 'width':285, 'height':115, 'attrs':'', 'meths':'__contains__|__eq__|__init__|__str__'} 9 | {'type':'umlshape', 'id':'CPEComponentSimple', 'x':256, 'y':659, 'width':208, 'height':189, 'attrs':'spechar_to_pce', 'meths':'__init__|__str__|as_fs|as_uri_2_3|as_wfn|get_value|set_value'} 10 | {'type':'umlshape', 'id':'CPEComponentUndefined', 'x':540, 'y':403, 'width':241, 'height':115, 'attrs':'', 'meths':'__contains__|__eq__|__init__|__str__'} 11 | {'type':'umlshape', 'id':'CPEComponent1_1', 'x':533, 'y':582, 'width':175, 'height':221, 'attrs':'SEPARATOR_COMP|NON_STANDARD_VALUES|VALUE_UNDEFINED|VALUE_EMPTY', 'meths':'__contains__|__repr__|as_fs|as_uri_2_3|as_wfn|set_value'} 12 | {'type':'umlshape', 'id':'CPEComponent2_2', 'x':548, 'y':830, 'width':175, 'height':141, 'attrs':'SEPARATOR_COMP|NON_STANDARD_VALUES|VALUE_UNDEFINED|VALUE_EMPTY', 'meths':'__repr__'} 13 | {'type':'umlshape', 'id':'CPEComponent2_3', 'x':548, 'y':1097, 'width':175, 'height':67, 'attrs':'', 'meths':'__repr__'} 14 | {'type':'umlshape', 'id':'CPEComponent2_3_FS', 'x':861, 'y':767, 'width':208, 'height':147, 'attrs':'SEPARATOR_COMP|SEPARATOR_LANG|VALUE_ANY|VALUE_NA|WILDCARD_MULTI|WILDCARD_ONE', 'meths':''} 15 | {'type':'umlshape', 'id':'CPEComponent2_3_URI', 'x':861, 'y':1182, 'width':219, 'height':227, 'attrs':'SEPARATOR_COMP|SEPARATOR_LANG|SEPARATOR_PACKED_EDITION|VALUE_ANY|VALUE_NA|VALUE_EMPTY|VALUE_UNDEFINED|WILDCARD_MULTI|WILDCARD_ONE|char_to_pce|pce_char_to_decode', 'meths':''} 16 | {'type':'umlshape', 'id':'CPEComponent2_3_URI_edpacked', 'x':811, 'y':1471, 'width':318, 'height':109, 'attrs':'SEPARATOR_COMP', 'meths':'__init__|set_value'} 17 | {'type':'umlshape', 'id':'CPEComponent2_3_WFN', 'x':866, 'y':958, 'width':219, 'height':205, 'attrs':'SEPARATOR_COMP|SEPARATOR_PAIR|SEPARATOR_LANG|VALUE_ANY|VALUE_NA|WILDCARD_MULTI|WILDCARD_ONE', 'meths':'get_value|set_value'} 18 | {'type':'edge', 'id':'CPEComponent_to_object', 'source':'CPEComponent', 'target':'object', 'uml_edge_type':'generalisation'} 19 | {'type':'edge', 'id':'CPEComponentAnyValue_to_CPEComponentLogical', 'source':'CPEComponentAnyValue', 'target':'CPEComponentLogical', 'uml_edge_type':'generalisation'} 20 | {'type':'edge', 'id':'CPEComponentEmpty_to_CPEComponentLogical', 'source':'CPEComponentEmpty', 'target':'CPEComponentLogical', 'uml_edge_type':'generalisation'} 21 | {'type':'edge', 'id':'CPEComponentLogical_to_CPEComponent', 'source':'CPEComponentLogical', 'target':'CPEComponent', 'uml_edge_type':'generalisation'} 22 | {'type':'edge', 'id':'CPEComponentNotApplicable_to_CPEComponentLogical', 'source':'CPEComponentNotApplicable', 'target':'CPEComponentLogical', 'uml_edge_type':'generalisation'} 23 | {'type':'edge', 'id':'CPEComponentSimple_to_CPEComponent', 'source':'CPEComponentSimple', 'target':'CPEComponent', 'uml_edge_type':'generalisation'} 24 | {'type':'edge', 'id':'CPEComponentUndefined_to_CPEComponentLogical', 'source':'CPEComponentUndefined', 'target':'CPEComponentLogical', 'uml_edge_type':'generalisation'} 25 | {'type':'edge', 'id':'CPEComponent1_1_to_CPEComponentSimple', 'source':'CPEComponent1_1', 'target':'CPEComponentSimple', 'uml_edge_type':'generalisation'} 26 | {'type':'edge', 'id':'CPEComponent2_2_to_CPEComponentSimple', 'source':'CPEComponent2_2', 'target':'CPEComponentSimple', 'uml_edge_type':'generalisation'} 27 | {'type':'edge', 'id':'CPEComponent2_3_to_CPEComponentSimple', 'source':'CPEComponent2_3', 'target':'CPEComponentSimple', 'uml_edge_type':'generalisation'} 28 | {'type':'edge', 'id':'CPEComponent2_3_FS_to_CPEComponent2_3', 'source':'CPEComponent2_3_FS', 'target':'CPEComponent2_3', 'uml_edge_type':'generalisation'} 29 | {'type':'edge', 'id':'CPEComponent2_3_URI_to_CPEComponent2_3', 'source':'CPEComponent2_3_URI', 'target':'CPEComponent2_3', 'uml_edge_type':'generalisation'} 30 | {'type':'edge', 'id':'CPEComponent2_3_URI_edpacked_to_CPEComponent2_3_URI', 'source':'CPEComponent2_3_URI_edpacked', 'target':'CPEComponent2_3_URI', 'uml_edge_type':'generalisation'} 31 | {'type':'edge', 'id':'CPEComponent2_3_WFN_to_CPEComponent2_3', 'source':'CPEComponent2_3_WFN', 'target':'CPEComponent2_3', 'uml_edge_type':'generalisation'} 32 | -------------------------------------------------------------------------------- /docs/_static/cpecomp/cpecomp_model_public.pyns.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilp0inter/cpe/50ba2ee28b5d6b24fa2c5b1493de9de953ca7dce/docs/_static/cpecomp/cpecomp_model_public.pyns.pdf -------------------------------------------------------------------------------- /docs/_static/cpelang/cpelang_model_all.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilp0inter/cpe/50ba2ee28b5d6b24fa2c5b1493de9de953ca7dce/docs/_static/cpelang/cpelang_model_all.png -------------------------------------------------------------------------------- /docs/_static/cpelang/cpelang_model_all.pyns: -------------------------------------------------------------------------------- 1 | # PynSource Version 1.1 2 | {'type':'meta', 'info1':'Lorem ipsum dolor sit amet, consectetur adipiscing elit is latin.'} 3 | {'type':'umlshape', 'id':'CPELanguage', 'x':145, 'y':82, 'width':131, 'height':157, 'attrs':'expression|path|document', 'meths':'__init__|__str__|language_match'} 4 | {'type':'umlshape', 'id':'object', 'x':172, 'y':20, 'width':76, 'height':31, 'attrs':'', 'meths':''} 5 | {'type':'umlshape', 'id':'CPELanguage2_2', 'x':228, 'y':289, 'width':164, 'height':93, 'attrs':'VERSION', 'meths':'language_match'} 6 | {'type':'umlshape', 'id':'CPELanguage2_3', 'x':20, 'y':284, 'width':170, 'height':173, 'attrs':'VERSION', 'meths':'_fact_ref_eval|_check_fact_ref_eval|_ocilcheck|_ovalcheck|_unbind|language_match'} 7 | {'type':'edge', 'id':'CPELanguage_to_object', 'source':'CPELanguage', 'target':'object', 'uml_edge_type':'generalisation'} 8 | {'type':'edge', 'id':'CPELanguage2_2_to_CPELanguage', 'source':'CPELanguage2_2', 'target':'CPELanguage', 'uml_edge_type':'generalisation'} 9 | {'type':'edge', 'id':'CPELanguage2_3_to_CPELanguage', 'source':'CPELanguage2_3', 'target':'CPELanguage', 'uml_edge_type':'generalisation'} 10 | -------------------------------------------------------------------------------- /docs/_static/cpelang/cpelang_model_all.pyns.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilp0inter/cpe/50ba2ee28b5d6b24fa2c5b1493de9de953ca7dce/docs/_static/cpelang/cpelang_model_all.pyns.pdf -------------------------------------------------------------------------------- /docs/_static/cpelang/cpelang_model_public.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilp0inter/cpe/50ba2ee28b5d6b24fa2c5b1493de9de953ca7dce/docs/_static/cpelang/cpelang_model_public.png -------------------------------------------------------------------------------- /docs/_static/cpelang/cpelang_model_public.pyns: -------------------------------------------------------------------------------- 1 | # PynSource Version 1.1 2 | {'type':'meta', 'info1':'Lorem ipsum dolor sit amet, consectetur adipiscing elit is latin.'} 3 | {'type':'umlshape', 'id':'CPELanguage', 'x':145, 'y':82, 'width':131, 'height':157, 'attrs':'expression|path|document', 'meths':'__init__|__str__|language_match'} 4 | {'type':'umlshape', 'id':'object', 'x':172, 'y':20, 'width':76, 'height':31, 'attrs':'', 'meths':''} 5 | {'type':'umlshape', 'id':'CPELanguage2_2', 'x':228, 'y':284, 'width':164, 'height':93, 'attrs':'VERSION', 'meths':'language_match'} 6 | {'type':'umlshape', 'id':'CPELanguage2_3', 'x':20, 'y':284, 'width':164, 'height':93, 'attrs':'VERSION', 'meths':'language_match'} 7 | {'type':'edge', 'id':'CPELanguage_to_object', 'source':'CPELanguage', 'target':'object', 'uml_edge_type':'generalisation'} 8 | {'type':'edge', 'id':'CPELanguage2_2_to_CPELanguage', 'source':'CPELanguage2_2', 'target':'CPELanguage', 'uml_edge_type':'generalisation'} 9 | {'type':'edge', 'id':'CPELanguage2_3_to_CPELanguage', 'source':'CPELanguage2_3', 'target':'CPELanguage', 'uml_edge_type':'generalisation'} 10 | -------------------------------------------------------------------------------- /docs/_static/cpelang/cpelang_model_public.pyns.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilp0inter/cpe/50ba2ee28b5d6b24fa2c5b1493de9de953ca7dce/docs/_static/cpelang/cpelang_model_public.pyns.pdf -------------------------------------------------------------------------------- /docs/_static/cpeset/cpeset_model_all.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilp0inter/cpe/50ba2ee28b5d6b24fa2c5b1493de9de953ca7dce/docs/_static/cpeset/cpeset_model_all.png -------------------------------------------------------------------------------- /docs/_static/cpeset/cpeset_model_all.pyns: -------------------------------------------------------------------------------- 1 | # PynSource Version 1.1 2 | {'type':'meta', 'info1':'Lorem ipsum dolor sit amet, consectetur adipiscing elit is latin.'} 3 | {'type':'umlshape', 'id':'CPESet', 'x':181, 'y':79, 'width':98, 'height':173, 'attrs':'K', 'meths':'__getitem__|__init__|__len__|__str__|append|name_match'} 4 | {'type':'umlshape', 'id':'object', 'x':192, 'y':10, 'width':76, 'height':31, 'attrs':'', 'meths':''} 5 | {'type':'umlshape', 'id':'CPESet1_1', 'x':26, 'y':308, 'width':109, 'height':125, 'attrs':'VERSION|K', 'meths':'append|name_match'} 6 | {'type':'umlshape', 'id':'CPESet2_2', 'x':176, 'y':308, 'width':109, 'height':125, 'attrs':'VERSION|K', 'meths':'append|name_match'} 7 | {'type':'umlshape', 'id':'CPESet2_3', 'x':328, 'y':258, 'width':194, 'height':365, 'attrs':'LOGICAL_VALUE_SUPERSET|LOGICAL_VALUE_SUBSET|LOGICAL_VALUE_EQUAL|LOGICAL_VALUE_DISJOINT|LOGICAL_VALUE_UNDEFINED|VERSION|K', 'meths':'_compare|_compare_strings|_contains_wildcards|_is_even_wildcards|_is_string|compare_wfns|cpe_disjoint|cpe_equal|cpe_subset|cpe_superset|append|name_match'} 8 | {'type':'edge', 'id':'CPESet_to_object', 'source':'CPESet', 'target':'object', 'uml_edge_type':'generalisation'} 9 | {'type':'edge', 'id':'CPESet_to_object', 'source':'CPESet', 'target':'object', 'uml_edge_type':'generalisation'} 10 | {'type':'edge', 'id':'CPESet1_1_to_CPESet', 'source':'CPESet1_1', 'target':'CPESet', 'uml_edge_type':'generalisation'} 11 | {'type':'edge', 'id':'CPESet_to_object', 'source':'CPESet', 'target':'object', 'uml_edge_type':'generalisation'} 12 | {'type':'edge', 'id':'CPESet1_1_to_CPESet', 'source':'CPESet1_1', 'target':'CPESet', 'uml_edge_type':'generalisation'} 13 | {'type':'edge', 'id':'CPESet2_2_to_CPESet', 'source':'CPESet2_2', 'target':'CPESet', 'uml_edge_type':'generalisation'} 14 | {'type':'edge', 'id':'CPESet_to_object', 'source':'CPESet', 'target':'object', 'uml_edge_type':'generalisation'} 15 | {'type':'edge', 'id':'CPESet1_1_to_CPESet', 'source':'CPESet1_1', 'target':'CPESet', 'uml_edge_type':'generalisation'} 16 | {'type':'edge', 'id':'CPESet2_2_to_CPESet', 'source':'CPESet2_2', 'target':'CPESet', 'uml_edge_type':'generalisation'} 17 | {'type':'edge', 'id':'CPESet2_3_to_CPESet', 'source':'CPESet2_3', 'target':'CPESet', 'uml_edge_type':'generalisation'} 18 | -------------------------------------------------------------------------------- /docs/_static/cpeset/cpeset_model_all.pyns.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilp0inter/cpe/50ba2ee28b5d6b24fa2c5b1493de9de953ca7dce/docs/_static/cpeset/cpeset_model_all.pyns.pdf -------------------------------------------------------------------------------- /docs/_static/cpeset/cpeset_model_public.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilp0inter/cpe/50ba2ee28b5d6b24fa2c5b1493de9de953ca7dce/docs/_static/cpeset/cpeset_model_public.png -------------------------------------------------------------------------------- /docs/_static/cpeset/cpeset_model_public.pyns: -------------------------------------------------------------------------------- 1 | # PynSource Version 1.1 2 | {'type':'meta', 'info1':'Lorem ipsum dolor sit amet, consectetur adipiscing elit is latin.'} 3 | {'type':'umlshape', 'id':'CPESet', 'x':181, 'y':79, 'width':98, 'height':173, 'attrs':'K', 'meths':'__getitem__|__init__|__len__|__str__|append|name_match'} 4 | {'type':'umlshape', 'id':'object', 'x':192, 'y':10, 'width':76, 'height':31, 'attrs':'', 'meths':''} 5 | {'type':'umlshape', 'id':'CPESet1_1', 'x':26, 'y':308, 'width':109, 'height':125, 'attrs':'VERSION|K', 'meths':'append|name_match'} 6 | {'type':'umlshape', 'id':'CPESet2_2', 'x':176, 'y':308, 'width':109, 'height':125, 'attrs':'VERSION|K', 'meths':'append|name_match'} 7 | {'type':'umlshape', 'id':'CPESet2_3', 'x':328, 'y':258, 'width':194, 'height':285, 'attrs':'LOGICAL_VALUE_SUPERSET|LOGICAL_VALUE_SUBSET|LOGICAL_VALUE_EQUAL|LOGICAL_VALUE_DISJOINT|LOGICAL_VALUE_UNDEFINED|VERSION|K', 'meths':'compare_wfns|cpe_disjoint|cpe_equal|cpe_subset|cpe_superset|append|name_match'} 8 | {'type':'edge', 'id':'CPESet_to_object', 'source':'CPESet', 'target':'object', 'uml_edge_type':'generalisation'} 9 | {'type':'edge', 'id':'CPESet_to_object', 'source':'CPESet', 'target':'object', 'uml_edge_type':'generalisation'} 10 | {'type':'edge', 'id':'CPESet1_1_to_CPESet', 'source':'CPESet1_1', 'target':'CPESet', 'uml_edge_type':'generalisation'} 11 | {'type':'edge', 'id':'CPESet_to_object', 'source':'CPESet', 'target':'object', 'uml_edge_type':'generalisation'} 12 | {'type':'edge', 'id':'CPESet1_1_to_CPESet', 'source':'CPESet1_1', 'target':'CPESet', 'uml_edge_type':'generalisation'} 13 | {'type':'edge', 'id':'CPESet2_2_to_CPESet', 'source':'CPESet2_2', 'target':'CPESet', 'uml_edge_type':'generalisation'} 14 | {'type':'edge', 'id':'CPESet_to_object', 'source':'CPESet', 'target':'object', 'uml_edge_type':'generalisation'} 15 | {'type':'edge', 'id':'CPESet1_1_to_CPESet', 'source':'CPESet1_1', 'target':'CPESet', 'uml_edge_type':'generalisation'} 16 | {'type':'edge', 'id':'CPESet2_2_to_CPESet', 'source':'CPESet2_2', 'target':'CPESet', 'uml_edge_type':'generalisation'} 17 | {'type':'edge', 'id':'CPESet2_3_to_CPESet', 'source':'CPESet2_3', 'target':'CPESet', 'uml_edge_type':'generalisation'} 18 | -------------------------------------------------------------------------------- /docs/_static/cpeset/cpeset_model_public.pyns.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilp0inter/cpe/50ba2ee28b5d6b24fa2c5b1493de9de953ca7dce/docs/_static/cpeset/cpeset_model_public.pyns.pdf -------------------------------------------------------------------------------- /docs/_static/matching.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilp0inter/cpe/50ba2ee28b5d6b24fa2c5b1493de9de953ca7dce/docs/_static/matching.png -------------------------------------------------------------------------------- /docs/bugtracker.rst: -------------------------------------------------------------------------------- 1 | Bugtracker 2 | ========== 3 | 4 | If you have any suggestions, bug reports or annoyances please report them to the issue tracker at ``_ 5 | -------------------------------------------------------------------------------- /docs/compatibility.rst: -------------------------------------------------------------------------------- 1 | Compatibility among CPE versions 2 | ================================ 3 | 4 | ======== ===================== ========================= ========================= ========================= ========================= 5 | VERSIONS 1.1 2.2 2.3 WFN 2.3 URI 2.3 FS 6 | ======== ===================== ========================= ========================= ========================= ========================= 7 | 1.1 Yes Depends of count of parts Depends of count of parts Depends of count of parts Depends of count of parts 8 | 2.2 Depends of characters Yes Yes Yes Yes 9 | 2.3 WFN Depends of characters Depends of characters Yes Yes Yes 10 | 2.3 URI Depends of characters Depends of characters Yes Yes Yes 11 | 2.3 FS Depends of characters Depends of characters Yes Yes Yes 12 | ======== ===================== ========================= ========================= ========================= ========================= 13 | -------------------------------------------------------------------------------- /docs/cpeversions.rst: -------------------------------------------------------------------------------- 1 | List of implemented CPE versions 2 | ================================ 3 | 4 | This package implements the validation of both CPE Names and platforms (set of CPE Names), and the comparisons between them, corresponding to some versions of CPE specification [`3 `_]. 5 | 6 | The functionality implemented in this package, associated with versions 1.1, 2.2 and 2.3 of CPE specification, is below: 7 | 8 | * **Version 1.1** [`4 `_]: 9 | 10 | * CPE naming 11 | * CPE Name matching 12 | 13 | * **Version 2.2** [`5 `_]: 14 | 15 | * CPE naming 16 | * CPE Name matching 17 | * CPE Language matching 18 | 19 | * **Version 2.3**: 20 | 21 | * CPE naming [`6 `_] 22 | * CPE Name matching [`7 `_] 23 | * CPE Applicability Language matching [`8 `_] 24 | 25 | The CPE naming of version 2.3 supports the definition of three different styles of CPE Name: 26 | 27 | * **WFN**: Well-Formed Name 28 | * **URI**: Uniform Resource Identifier 29 | * **FS**: Formatted String 30 | -------------------------------------------------------------------------------- /docs/examples.rst: -------------------------------------------------------------------------------- 1 | Usage examples 2 | ============== 3 | 4 | This section explains with several examples how to use this package to create both CPE Names and platforms in a particular version of CPE specification. 5 | 6 | Naming 7 | ------ 8 | 9 | To create a new CPE Name, the cpe package provides a generating class of CPE objects called CPE. It implements the factory pattern and receive two parameters: version of CPE specification and URI associated with CPE Name. Also, it is possible create a instance of a particular version of CPE Name directly using the class associated with the version. 10 | 11 | In the following example, some CPE Names of different versions of CPE specification are created: 12 | 13 | * Imports the class:: 14 | 15 | >>> from cpe import CPE 16 | 17 | * Creates a CPE Name of version 1.1 with an operating system and an application parts, without setting the version directly (auto version):: 18 | 19 | >>> str11 = 'cpe://redhat:enterprise_linux:3:as/apache:httpd:2.0.52' 20 | >>> c11 = CPE(str11) 21 | 22 | * Creates a CPE Name of version 2.2 with an operating system where the version is set (manual version):: 23 | 24 | >>> str22 = 'cpe:/o:redhat:enterprise_linux:4:update4' 25 | >>> c22 = CPE(str22, CPE.VERSION_2_2) 26 | 27 | * Creates a CPE Name of version 2.3 (URI style) with an application system where the value of edition component is packed:: 28 | 29 | >>> str23_uri = 'cpe:/a:hp:insight_diagnostics:8::~~online~win2003~x64~' 30 | >>> c23_uri = CPE(str23_uri) 31 | 32 | * Creates a CPE Name of version 2.3 (WFN style) with an application system where some values have wildcards:: 33 | 34 | >>> str23_wfn = 'wfn:[part="a", vendor="hp", product="?insight_diagnostics?", version="8\.*", target_sw=ANY, target_hw="x32"]' 35 | >>> c23_wfn = CPE(str23_wfn) 36 | 37 | * Creates a CPE Name of version 2.3 (formatted string style) with a hardware system:: 38 | 39 | >>> str23_fs = 'cpe:2.3:h:cisco:ios:12.3:enterprise:*:*:*:*:*:*' 40 | >>> c23_fs = CPE(str23_fs) 41 | 42 | The cpe package provides methods to get the value of components of a CPE Name (these functions always return a string list) and identify the type of system associated with it (hardware, operating system or application):: 43 | 44 | >>> c11.get_product() # Compound product attribute (v1.1) 45 | ['enterprise_linux', 'httpd'] 46 | >>> c22.get_update() # Simple Update attribute (v2.2) 47 | ['update4'] 48 | >>> c23_uri.get_target_hardware() # Simple Target_hw attribute (v2.3, URI style) 49 | ['x64'] 50 | >>> c23_wfn.get_target_hardware() # Simple Target_hw attribute (v2.3, WFN style) 51 | ['"x32"'] 52 | >>> c23_wfn.get_target_software() # Target_sw attribute with logical value(v2.3, WFN style) 53 | ['ANY'] 54 | >>> c23_fs.is_hardware() # Type of system (v2.3, formatted string style) 55 | True 56 | 57 | Finally, the cpe package contains methods to convert any CPE Name defined under a particular style (URI version 2.3, WFN or formatted string) in other different styles:: 58 | 59 | >>> c22.as_wfn() 60 | 'wfn:[part="o", vendor="redhat", product="enterprise_linux", version="4", update="update4"]' 61 | >>> c23_uri.as_uri_2_3() 62 | 'cpe:/a:hp:insight_diagnostics:8::~~online~win2003~x64~' 63 | >>> c23_wfn.as_fs() 64 | 'cpe:2.3:a:hp:?insight_diagnostics?:8.*:*:*:*:*:*:x32:*' 65 | 66 | Name matching 67 | ------------- 68 | 69 | To create a set of CPE Name the package cpe provides the CPESetX\_Y class, where X\_Y is the target version of CPE specification. The *name_match* function of set allows do the name matching of CPE specification. 70 | 71 | In the following example, a set of CPE Names of version 2.2 is created and the name matching is realized: 72 | 73 | * Imports the classes of version:: 74 | 75 | >>> from cpe.cpe2_2 import CPE2_2 76 | >>> from cpe.cpeset2_2 import CPESet2_2 77 | 78 | * Creates the CPE Names of target system:: 79 | 80 | >>> c1 = CPE2_2('cpe:/o:microsoft:windows_2000::sp3:pro') 81 | >>> c2 = CPE2_2('cpe:/a:microsoft:ie:5.5') 82 | 83 | * Creates a set that contains the above CPE Names (known instances): K = {"cpe:/o:microsoft:windows\_2000::sp3:pro", "cpe:/a:microsoft:ie:5.5"}:: 84 | 85 | >>> K = CPESet2_2() 86 | >>> K.append(c1) 87 | >>> K.append(c2) 88 | 89 | * Create the candidate CPE Name. It represents a rule in a security guidance checklist describes some settings to check on a system running Microsoft Windows 2000: X = "cpe:/o:microsoft:windows\_2000":: 90 | 91 | >>> X = CPE2_2('cpe:/o:microsoft:windows_2000') 92 | 93 | * Does the name matching:: 94 | 95 | >>> K.name_match(X) 96 | True 97 | 98 | There are three components in X: C1=o, C2=microsoft, C3=windows\_2000. Each component matches the corresponding component of the first CPE Name in K. So, the algorithm returns true and the rule can be applied to the target system. 99 | 100 | Language matching 101 | ----------------- 102 | 103 | To create an expression of CPE Language the cpe package provides the CPELanguageX\_Y class, where X\_Y is the version of CPE specification used. The *language_match* function of class allows do the language matching of CPE specification. 104 | 105 | In the following example, an expression of CPE Language of version 2.2 is created and the language matching is done: 106 | 107 | * Imports the classes of version:: 108 | 109 | >>> from cpe import CPE 110 | >>> from cpe.cpeset2_2 import CPESet2_2 111 | >>> from cpe.cpelang2_2 import CPELanguage2_2 112 | 113 | * Creates the CPE Names of target system:: 114 | 115 | >>> c1 = CPE('cpe:/o:sun:solaris:5.9:::en-us', CPE.VERSION_2_2) 116 | >>> c2 = CPE('cpe:/a:bea:weblogic:8.1', CPE.VERSION_2_2) 117 | 118 | * Creates a set that contains the above CPE Names (known instances): K = {"cpe:/o:sun:sunos:5.9:::en-us", "cpe:/a:bea:weblogic:8.1"}:: 119 | 120 | >>> K = CPESet2_2() 121 | >>> K.append(c1) 122 | >>> K.append(c2) 123 | 124 | * Creates the expression in XML of candidate CPE Language statement: 125 | 126 | X = 127 | Sun Solaris 5.8 or 5.9 with BEA Weblogic 8.1 installed 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | :: 146 | 147 | >>> It is necessary specify the "cpe:platform-specification" tag 148 | >>> document = '''Sun Solaris 5.8 or 5.9 with BEA Weblogic 8.1 installed''' 149 | 150 | * Does the language matching:: 151 | 152 | >>> X = CPELanguage2_2(document) 153 | >>> X.language_match(K) 154 | True 155 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. CPE documentation master file, created by 2 | sphinx-quickstart on Wed Jun 26 01:11:34 2013. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | CPE PACKAGE 7 | =========== 8 | 9 | Welcome to cpe package documentation. In this pages you can find a tutorial about cpe package, that implements the validation of both CPE Names and platform (set of CPE Names) and the comparisons between them, corresponding to versions 1.1, 2.2 and 2.3 of CPE (Common Platform Enumeration) specification. Also, this package gives support to name and language matching algorithms. 10 | 11 | This documentation contains a brief introduction about Common Platform Enumeration (CPE) specification, the CPE version list implemented and the compatibility among them, the class model designed, the steps to install and use the cpe package (with examples), and several important issues to consider associated with the functionality of the package. 12 | 13 | For more information about cpe package implementation, please visite: ``_. 14 | 15 | Contents: 16 | 17 | .. toctree:: 18 | :maxdepth: 4 19 | 20 | intro 21 | cpeversions 22 | compatibility 23 | model 24 | install 25 | examples 26 | issues 27 | bugtracker 28 | todo 29 | references 30 | 31 | Indices and tables 32 | ================== 33 | 34 | * :ref:`genindex` 35 | * :ref:`search` 36 | 37 | -------------------------------------------------------------------------------- /docs/install.rst: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | 4 | Install the package using pip:: 5 | 6 | pip install cpe 7 | 8 | or execute the setup.py file in package:: 9 | 10 | python setup.py install 11 | 12 | -------------------------------------------------------------------------------- /docs/intro.rst: -------------------------------------------------------------------------------- 1 | Introduction 2 | ============ 3 | 4 | Common Platform Enumeration (CPE) is a standardized method of describing and identifying classes of applications, operating systems, and hardware devices present among an enterprise's computing assets. CPE does not identify unique instantiations of products on systems, such as the installation of XYZ Visualizer Enterprise Suite 4.2.3 with serial number Q472B987P113. Rather, CPE identifies abstract classes of products, such as XYZ Visualizer Enterprise Suite 4.2.3, XYZ Visualizer Enterprise Suite (all versions), or XYZ Visualizer (all variations). 5 | 6 | IT management tools can collect information about installed products, identifying these products using their CPE Names, and then use this standardized information to help make fully or partially automated decisions regarding the assets. For example, identifying the presence of XYZ Visualizer Enterprise Suite could trigger a vulnerability management tool to check the system for known vulnerabilities in the software, and also trigger a configuration management tool to verify that the software is configured securely in accordance with the organization's policies. This example illustrates how CPE Names can be used as a standardized source of information for enforcing and verifying IT management policies across tools [`1 `_]. 7 | 8 | CPE provides [`2 `_]: 9 | 10 | - A standard machine-readable format for encoding names of IT products and platforms (naming). 11 | - A set of procedures for comparing names (name matching). 12 | - A language for constructing "applicability statements" that combine CPE Names with simple logical operators (language matching). 13 | - A standard notion of a CPE Dictionary. 14 | 15 | For more information, please visit the official website of CPE, maintained by MITRE: ``_ 16 | 17 | .. image:: _static/cpe_logo.gif 18 | 19 | 20 | Matching 21 | -------- 22 | 23 | Matching [5] is the process of determining if a given CPE Name or CPE Language statement specifies a platform that is defined by a set of known CPE Names. It helps define the relationship between different CPE Names (or language statements). 24 | 25 | Conceptual model 26 | ~~~~~~~~~~~~~~~~ 27 | 28 | The conceptual model for matching consists of two steps: 29 | 30 | #. Make a list of all the CPE Names and logical connections. 31 | #. For each name, check whether the target system has the hardware, software, or operating system indicated by the name. If the check succeeds for all names, and satisfies the logical constraints, then the target is an instance of the CPE Name or Language representation. 32 | 33 | Matching Algorithm: Known Instance Based Matching 34 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 35 | 36 | Two elements participate in the matching process: the known instance set (CPE Names that define the target system) and the candidate CPE Name or Language expression. The algorithm applies the "filter" indicated by X and replies to the question: "Does the filter X return any instance of target system K?" 37 | 38 | The figure bellow illustrates the basic concept of known instance based matching: 39 | 40 | .. image:: _static/matching.png 41 | 42 | Matching consists of two algorithms. 43 | 44 | * CPE\_Name\_Match: 45 | 46 | * This algorithm accepts a set of CPE Names K and a candidate CPE Name X. 47 | * It returns true if X matches any member of K, and false otherwise. 48 | 49 | * CPE\_Language\_Match: 50 | 51 | * This algorithm accepts a set of CPE Names K and a candidate expression E. 52 | * It returns true if the expression can be satisfied by name matching against the members of K, and false otherwise. 53 | -------------------------------------------------------------------------------- /docs/issues.rst: -------------------------------------------------------------------------------- 1 | Important issues 2 | ================ 3 | 4 | * The **auto version classes** receive an CPE Name and try to find out what version is associated. 5 | * The **functions to get the values of attributes of a CPE Name** always return a list of string. That is so because the attributes of version 1.1 of CPE specification can be linked with several system and elements. For example, the attribute *vendor* in CPE Name *cpe://sun:sunos:5.9/bea:weblogic:8.1;mysql:server:5.0* get three values: *sun*, *bea* and *mysql*. 6 | * The **not logical values of the attributes in version 2.3** of CPE specification always start and end with double quotes. For example, the value of attribute *product* in CPE Name *wfn:[part="a", vendor="microsoft", product="internet_explorer", version="8", update="beta"]* is *"internet\_explorer"*, not *internet\_explorer* without double quotes. 7 | * Some **CPE Names of version 1.1 with several systems or elements defined** cannot convert into other CPE versions, for example, the CPE Name *cpe://sun:sunos:5.9/bea:weblogic:8.1;mysql:server:5.0* 8 | * **Comparing a CPE Name of version 1.1 with others**, if versions are incompatible, then the return value is *False* instead of raising an exception. 9 | * The methods :func:`ovalcheck` and :func:`ocilcheck` of :class:`CPELanguage2_3` class is **not implemented**. 10 | * The language attribute of CPE Names only allow the normal language tags according to the shortest ISO 639 code in language part and the ISO 3166-1 and UN M.49 code in region part. The extended, registered or reserved subtags are not supported. 11 | -------------------------------------------------------------------------------- /docs/model.rst: -------------------------------------------------------------------------------- 1 | Model 2 | ===== 3 | 4 | This section shows the diagrams of model parts of cpe package. These diagrams have been generated with the PyNSource tool version 1.61 (`https://code.google.com/p/pynsource/ `_). Each model class is stored in a different file. The model parts are as follows. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | model/cpehierarchy 10 | model/cpesethierarchy 11 | model/cpelanghierarchy 12 | model/cpecomphierarchy 13 | 14 | Categories of main classes 15 | -------------------------- 16 | 17 | The main classes of model can be grouped in four categories: 18 | 19 | * Auto version (classes to create CPE Names without setting their version of CPE specification associated): 20 | 21 | * **cpe.py** (generic auto version class) 22 | * **cpe2\_3.py** (auto version class of version 2.3) 23 | 24 | * Manual version (classes to create CPE Names of particular version of CPE specification): 25 | 26 | * **cpe1\_1.py** (version 1.1) 27 | * **cpe2\_2.py** (version 2.2) 28 | * **cpe2\_3\_wfn.py** (version 2.3 with WFN style) 29 | * **cpe2\_3\_uri,py** (version 2.3 with URI style) 30 | * **cpe2\_3\_fs.py** (version 2.3 with formatted style style) 31 | 32 | * CPE Name matching (classes to realize the name matching of CPE specification): 33 | 34 | * **cpeset1\_1.py** (version 1.1) 35 | * **cpeset2\_2.py** (version 2.2) 36 | * **cpeset2\_3.py** (version 2.3) 37 | 38 | * CPE Language matching (classes to realize the language matching of CPE specification): 39 | 40 | * **cpelang2\_2.py** (version 2.2) 41 | * **cpelang2\_3.py** (version 2.3) 42 | -------------------------------------------------------------------------------- /docs/model/cpecomphierarchy.rst: -------------------------------------------------------------------------------- 1 | CPEComponent hierarchy 2 | ====================== 3 | 4 | This section contains the classes associated with the types of components of versions of CPE Names implemented in this package: logical and simple. 5 | 6 | Class list 7 | ---------- 8 | 9 | The generic component class is: 10 | 11 | .. toctree:: 12 | 13 | cpecomphierarchy/cpecomp 14 | 15 | The logical components classes are: 16 | 17 | .. toctree:: 18 | 19 | cpecomphierarchy/cpecomp_logical 20 | cpecomphierarchy/cpecomp_anyvalue 21 | cpecomphierarchy/cpecomp_empty 22 | cpecomphierarchy/cpecomp_notapplicable 23 | cpecomphierarchy/cpecomp_undefined 24 | 25 | The simple components classes are: 26 | 27 | .. toctree:: 28 | 29 | cpecomphierarchy/cpecomp_simple 30 | cpecomphierarchy/cpecomp1_1 31 | cpecomphierarchy/cpecomp2_2 32 | cpecomphierarchy/cpecomp2_3 33 | cpecomphierarchy/cpecomp2_3_uri 34 | cpecomphierarchy/cpecomp2_3_uri_edpacked 35 | cpecomphierarchy/cpecomp2_3_wfn 36 | cpecomphierarchy/cpecomp2_3_fs 37 | 38 | Class diagram 39 | ------------- 40 | 41 | The class diagrams of CPE component hierarchy are available in multiple format: PNG, PDF and PYNS (output format of PyNSource tool). Listed below are the download links of these diagrams and their formats: 42 | 43 | * Classes with public and private attributes and methods: 44 | 45 | * `Formato PNG <../_static/cpecomp/cpecomp_model_all.png>`__ 46 | * `Formato PDF <../_static/cpecomp/cpecomp_model_all.pyns.pdf>`__ 47 | * `Formato PYNS <../_static/cpecomp/cpecomp_model_all.pyns>`__ 48 | 49 | * Classes with only public attributes and methods: 50 | 51 | * `Formato PNG <../_static/cpecomp/cpecomp_model_public.png>`__ 52 | * `Formato PDF <../_static/cpecomp/cpecomp_model_public.pyns.pdf>`__ 53 | * `Formato PYNS <../_static/cpecomp/cpecomp_model_public.pyns>`__ 54 | 55 | Next image presents the public attributes and methods of CPE component classes: 56 | 57 | .. image:: ../_static/cpecomp/cpecomp_model_public.png 58 | -------------------------------------------------------------------------------- /docs/model/cpecomphierarchy/cpecomp.rst: -------------------------------------------------------------------------------- 1 | CPEComponent class 2 | ================== 3 | 4 | .. autoclass:: cpe.comp.cpecomp.CPEComponent 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpecomphierarchy/cpecomp1_1.rst: -------------------------------------------------------------------------------- 1 | CPEComponent1_1 class 2 | ===================== 3 | 4 | .. autoclass:: cpe.comp.cpecomp1_1.CPEComponent1_1 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpecomphierarchy/cpecomp2_2.rst: -------------------------------------------------------------------------------- 1 | CPEComponent2_2 class 2 | ===================== 3 | 4 | .. autoclass:: cpe.comp.cpecomp2_2.CPEComponent2_2 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpecomphierarchy/cpecomp2_3.rst: -------------------------------------------------------------------------------- 1 | CPEComponent2_3 class 2 | ===================== 3 | 4 | .. autoclass:: cpe.comp.cpecomp2_3.CPEComponent2_3 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpecomphierarchy/cpecomp2_3_fs.rst: -------------------------------------------------------------------------------- 1 | CPEComponent2_3_FS class 2 | ======================== 3 | 4 | .. autoclass:: cpe.comp.cpecomp2_3_fs.CPEComponent2_3_FS 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpecomphierarchy/cpecomp2_3_uri.rst: -------------------------------------------------------------------------------- 1 | CPEComponent2_3_URI class 2 | ========================= 3 | 4 | .. autoclass:: cpe.comp.cpecomp2_3_uri.CPEComponent2_3_URI 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpecomphierarchy/cpecomp2_3_uri_edpacked.rst: -------------------------------------------------------------------------------- 1 | CPEComponent2_3_edpacked class 2 | ============================== 3 | 4 | .. autoclass:: cpe.comp.cpecomp2_3_uri_edpacked.CPEComponent2_3_URI_edpacked 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpecomphierarchy/cpecomp2_3_wfn.rst: -------------------------------------------------------------------------------- 1 | CPEComponent2_3_WFN class 2 | ========================= 3 | 4 | .. autoclass:: cpe.comp.cpecomp2_3_wfn.CPEComponent2_3_WFN 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpecomphierarchy/cpecomp_anyvalue.rst: -------------------------------------------------------------------------------- 1 | CPEComponentAnyValue class 2 | ========================== 3 | 4 | .. autoclass:: cpe.comp.cpecomp_anyvalue.CPEComponentAnyValue 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpecomphierarchy/cpecomp_empty.rst: -------------------------------------------------------------------------------- 1 | CPEComponentEmpty class 2 | ======================= 3 | 4 | .. autoclass:: cpe.comp.cpecomp_empty.CPEComponentEmpty 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpecomphierarchy/cpecomp_logical.rst: -------------------------------------------------------------------------------- 1 | CPEComponentLogical class 2 | ========================= 3 | 4 | .. autoclass:: cpe.comp.cpecomp_logical.CPEComponentLogical 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpecomphierarchy/cpecomp_notapplicable.rst: -------------------------------------------------------------------------------- 1 | CPEComponentNotApplicable class 2 | =============================== 3 | 4 | .. autoclass:: cpe.comp.cpecomp_notapplicable.CPEComponentNotApplicable 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpecomphierarchy/cpecomp_simple.rst: -------------------------------------------------------------------------------- 1 | CPEComponentSimple class 2 | ======================== 3 | 4 | .. autoclass:: cpe.comp.cpecomp_simple.CPEComponentSimple 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpecomphierarchy/cpecomp_undefined.rst: -------------------------------------------------------------------------------- 1 | CPEComponentUndefined class 2 | =========================== 3 | 4 | .. autoclass:: cpe.comp.cpecomp_undefined.CPEComponentUndefined 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpehierarchy.rst: -------------------------------------------------------------------------------- 1 | CPE hierarchy 2 | ============= 3 | 4 | This section contains the classes associated with versions of CPE specification implemented in this package. 5 | 6 | Class list 7 | ---------- 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | 12 | cpehierarchy/cpe 13 | cpehierarchy/cpe1_1 14 | cpehierarchy/cpe2_2 15 | cpehierarchy/cpe2_3 16 | cpehierarchy/cpe2_3_uri 17 | cpehierarchy/cpe2_3_wfn 18 | cpehierarchy/cpe2_3_fs 19 | 20 | Class diagram 21 | ------------- 22 | 23 | The class diagrams of CPE hierarchy are available in multiple format: PNG, PDF and PYNS (output format of PyNSource tool). Listed below are the download links of these diagrams and their formats: 24 | 25 | * Classes with public and private attributes and methods: 26 | 27 | * `Formato PNG <../_static/cpe/cpe_model_all.png>`__ 28 | * `Formato PDF <../_static/cpe/cpe_model_all.pyns.pdf>`__ 29 | * `Formato PYNS <../_static/cpe/cpe_model_all.pyns>`__ 30 | 31 | * Classes with only public attributes and methods: 32 | 33 | * `Formato PNG <../_static/cpe/cpe_model_public.png>`__ 34 | * `Formato PDF <../_static/cpe/cpe_model_public.pyns.pdf>`__ 35 | * `Formato PYNS <../_static/cpe/cpe_model_public.pyns>`__ 36 | 37 | Next image presents the public attributes and methods of CPE classes: 38 | 39 | .. image:: ../_static/cpe/cpe_model_public.png 40 | -------------------------------------------------------------------------------- /docs/model/cpehierarchy/cpe.rst: -------------------------------------------------------------------------------- 1 | CPE class 2 | ========= 3 | 4 | .. autoclass:: cpe.cpe.CPE 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpehierarchy/cpe1_1.rst: -------------------------------------------------------------------------------- 1 | CPE1_1 class 2 | ============ 3 | 4 | .. autoclass:: cpe.cpe1_1.CPE1_1 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpehierarchy/cpe2_2.rst: -------------------------------------------------------------------------------- 1 | CPE2_2 class 2 | ============ 3 | 4 | .. autoclass:: cpe.cpe2_2.CPE2_2 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpehierarchy/cpe2_3.rst: -------------------------------------------------------------------------------- 1 | CPE2_3 class 2 | ============ 3 | 4 | .. autoclass:: cpe.cpe2_3.CPE2_3 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpehierarchy/cpe2_3_fs.rst: -------------------------------------------------------------------------------- 1 | CPE2_3_FS class 2 | =============== 3 | 4 | .. autoclass:: cpe.cpe2_3_fs.CPE2_3_FS 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpehierarchy/cpe2_3_uri.rst: -------------------------------------------------------------------------------- 1 | CPE2_3_URI class 2 | ================ 3 | 4 | .. autoclass:: cpe.cpe2_3_uri.CPE2_3_URI 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpehierarchy/cpe2_3_wfn.rst: -------------------------------------------------------------------------------- 1 | CPE2_3_WFN class 2 | ================ 3 | 4 | .. autoclass:: cpe.cpe2_3_wfn.CPE2_3_WFN 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpelanghierarchy.rst: -------------------------------------------------------------------------------- 1 | CPELanguage hierarchy 2 | ===================== 3 | 4 | This section contains the classes associated with the language matching algorithm of versions of CPE specification implemented in this package. 5 | 6 | Class list 7 | ---------- 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | 12 | cpelanghierarchy/cpelang 13 | cpelanghierarchy/cpelang2_2 14 | cpelanghierarchy/cpelang2_3 15 | 16 | Class diagram 17 | ------------- 18 | 19 | The class diagrams of CPELanguage hierarchy are available in multiple format: PNG, PDF and PYNS (output format of PyNSource tool). Listed below are the download links of these diagrams and their formats: 20 | 21 | * Classes with public and private attributes and methods: 22 | 23 | * `Formato PNG <../_static/cpelang/cpelang_model_all.png>`__ 24 | * `Formato PDF <../_static/cpelang/cpelang_model_all.pyns.pdf>`__ 25 | * `Formato PYNS <../_static/cpelang/cpelang_model_all.pyns>`__ 26 | 27 | * Classes with only public attributes and methods: 28 | 29 | * `Formato PNG <../_static/cpelang/cpelang_model_public.png>`__ 30 | * `Formato PDF <../_static/cpelang/cpelang_model_public.pyns.pdf>`__ 31 | * `Formato PYNS <../_static/cpelang/cpelang_model_public.pyns>`__ 32 | 33 | Next image presents the public attributes and methods of CPELanguage classes: 34 | 35 | .. image:: ../_static/cpelang/cpelang_model_public.png 36 | -------------------------------------------------------------------------------- /docs/model/cpelanghierarchy/cpelang.rst: -------------------------------------------------------------------------------- 1 | CPELanguage class 2 | ================= 3 | 4 | .. autoclass:: cpe.cpelang.CPELanguage 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpelanghierarchy/cpelang2_2.rst: -------------------------------------------------------------------------------- 1 | CPELanguage2_2 class 2 | ==================== 3 | 4 | .. autoclass:: cpe.cpelang2_2.CPELanguage2_2 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpelanghierarchy/cpelang2_3.rst: -------------------------------------------------------------------------------- 1 | CPELanguage2_3 class 2 | ==================== 3 | 4 | .. autoclass:: cpe.cpelang2_3.CPELanguage2_3 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpesethierarchy.rst: -------------------------------------------------------------------------------- 1 | CPESet hierarchy 2 | ================ 3 | 4 | This section contains the classes associated with the name matching algorithm of versions of CPE specification implemented in this package. 5 | 6 | Class list 7 | ---------- 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | 12 | cpesethierarchy/cpeset 13 | cpesethierarchy/cpeset1_1 14 | cpesethierarchy/cpeset2_2 15 | cpesethierarchy/cpeset2_3 16 | 17 | Class diagram 18 | ------------- 19 | 20 | The class diagrams of CPESet hierarchy are available in multiple format: PNG, PDF and PYNS (output format of PyNSource tool). Listed below are the download links of these diagrams and their formats: 21 | 22 | * Classes with public and private attributes and methods: 23 | 24 | * `Formato PNG <../_static/cpeset/cpeset_model_all.png>`__ 25 | * `Formato PDF <../_static/cpeset/cpeset_model_all.pyns.pdf>`__ 26 | * `Formato PYNS <../_static/cpeset/cpeset_model_all.pyns>`__ 27 | 28 | * Classes with only public attributes and methods: 29 | 30 | * `Formato PNG <../_static/cpeset/cpeset_model_public.png>`__ 31 | * `Formato PDF <../_static/cpeset/cpeset_model_public.pyns.pdf>`__ 32 | * `Formato PYNS <../_static/cpeset/cpeset_model_public.pyns>`__ 33 | 34 | Next image presents the public attributes and methods of CPESet classes: 35 | 36 | .. image:: ../_static/cpeset/cpeset_model_public.png 37 | -------------------------------------------------------------------------------- /docs/model/cpesethierarchy/cpeset.rst: -------------------------------------------------------------------------------- 1 | CPESet class 2 | ============ 3 | 4 | .. autoclass:: cpe.cpeset.CPESet 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpesethierarchy/cpeset1_1.rst: -------------------------------------------------------------------------------- 1 | CPESet1_1 class 2 | =============== 3 | 4 | .. autoclass:: cpe.cpeset1_1.CPESet1_1 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpesethierarchy/cpeset2_2.rst: -------------------------------------------------------------------------------- 1 | CPESet2_2 class 2 | =============== 3 | 4 | .. autoclass:: cpe.cpeset2_2.CPESet2_2 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/model/cpesethierarchy/cpeset2_3.rst: -------------------------------------------------------------------------------- 1 | CPESet2_3 class 2 | =============== 3 | 4 | .. autoclass:: cpe.cpeset2_3.CPESet2_3 5 | :members: 6 | :special-members: 7 | -------------------------------------------------------------------------------- /docs/references.rst: -------------------------------------------------------------------------------- 1 | References 2 | ========== 3 | 4 | * [1] CPE: ``_ 5 | * [2] About CPE: ``_ 6 | * [3] CPE Archive: ``_ 7 | * [4] CPE 1.1: ``_ 8 | * [5] CPE 2.2: ``_ 9 | * [6] CPE 2.3 - Naming Specification: ``_ 10 | * [7] CPE 2.3 - Name Matching Specification: ``_ 11 | * [8] CPE 2.3 - Applicability Language Specification: ``_ 12 | -------------------------------------------------------------------------------- /docs/todo.rst: -------------------------------------------------------------------------------- 1 | TODO 2 | ==== 3 | 4 | * Implement methods *ovalcheck* and *ocilcheck* of :class:`CPELanguage2_3` class. 5 | * Implement versions 2.0 and 2.1 of CPE specification. 6 | * Implement methods *as\_uri\_1\_1* and *as\_uri\_2\_2* to convert any CPE Name into a CPE Name of versions 1.1 and 2.2 respectively. 7 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | Sphinx==1.2.2 2 | pytest 3 | pytest-cov 4 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [egg_info] 2 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | from __future__ import absolute_import, unicode_literals 4 | 5 | from io import open 6 | import os 7 | import setuptools 8 | 9 | BASE_DIR = os.path.dirname(__file__) 10 | PKG_DIR = os.path.join(BASE_DIR, "cpe") 11 | 12 | meta = {} 13 | with open(os.path.join(PKG_DIR, "__meta__.py"), 'rb') as f: 14 | exec(f.read(), meta) 15 | 16 | with open(os.path.join(BASE_DIR, "README.rst"), encoding="utf-8") as f: 17 | long_description = f.read() 18 | 19 | 20 | setuptools.setup( 21 | name=meta["__packagename__"], 22 | version=meta["__version__"], 23 | description=meta["__summary__"], 24 | long_description=long_description, 25 | classifiers=[ 26 | "Development Status :: 5 - Production/Stable", 27 | "Intended Audience :: Developers", 28 | "Intended Audience :: Information Technology", 29 | "Intended Audience :: System Administrators", 30 | "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)", 31 | "Natural Language :: English", 32 | "Operating System :: OS Independent", 33 | "Programming Language :: Python :: 2.7" 34 | ], 35 | keywords=meta["__keywords__"], 36 | author=meta["__author__"], 37 | author_email=meta["__email__"], 38 | maintainer=meta["__maintainer__"], 39 | maintainer_email=meta["__maintainer_email__"], 40 | license=meta["__license__"], 41 | url=meta["__url__"], 42 | include_package_data=False, 43 | packages=setuptools.find_packages(exclude=['tests', 'docs']), 44 | ) 45 | -------------------------------------------------------------------------------- /tests/expression2_2.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Windows with secedit.exe tool 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /tests/expression2_3.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "operator": "AND", 4 | "children": [ 5 | { 6 | "operator": "OR", 7 | "children": [], 8 | "cpe_match": [ 9 | { 10 | "vulnerable": true, 11 | "cpe23Uri": "cpe:2.3:o:sun:solaris:5.8:*:*:*:*:*:*:*", 12 | "cpe_name": [] 13 | }, 14 | { 15 | "vulnerable": true, 16 | "cpe23Uri": "cpe:2.3:o:sun:solaris:5.9:*:*:*:*:*:*:*", 17 | "cpe_name": [] 18 | } 19 | ] 20 | }, 21 | { 22 | "operator": "OR", 23 | "children": [], 24 | "cpe_match": [ 25 | { 26 | "vulnerable": true, 27 | "cpe23Uri": "cpe:2.3:a:bea:weblogic:8.1:*:*:*:*:*:*:*", 28 | "cpe_name": [] 29 | } 30 | ] 31 | } 32 | ], 33 | "cpe_match": [] 34 | } 35 | ] -------------------------------------------------------------------------------- /tests/expression2_3.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Sun Solaris 5.8 or 5.9 with BEA Weblogic 8.1 installed 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tests/testfile_cpe2_3.txt: -------------------------------------------------------------------------------- 1 | >>> from cpe.cpe2_3 import CPE2_3 2 | 3 | ------------------------------------------------------------- 4 | Test for __new__(cls, cpe_str, *args, **kwargs): 5 | ------------------------------------------------------------- 6 | 7 | - TEST: WFN 8 | >>> str = r'wfn:[part="a", vendor="foo\\bar", product="big\$money", version="2010", update=ANY, edition=ANY, language=ANY, sw_edition="special", target_sw="ipod_touch", target_hw="80gb", other=ANY]' 9 | >>> c = CPE2_3(str) 10 | 11 | - TEST: formatted string 12 | >>> fs = 'cpe:2.3:a:hp:insight_diagnostics:8.*:es?:*:-:-:x32:*:*' 13 | >>> c = CPE2_3(fs) 14 | 15 | - TEST: URI 16 | >>> str = 'cpe:/a:hp:insight_diagnostics:7.4.0.1570::~~online~win2003~x64~' 17 | >>> c = CPE2_3(str) 18 | -------------------------------------------------------------------------------- /tests/testfile_cpe2_3_fs.txt: -------------------------------------------------------------------------------- 1 | >>> from __future__ import print_function 2 | >>> from cpe.cpe2_3_fs import CPE2_3_FS 3 | >>> from cpe.comp.cpecomp_simple import CPEComponentSimple 4 | 5 | ---------------------------------- 6 | Test for _get_attribute_values(self) 7 | ---------------------------------- 8 | 9 | TEST: 10 | >>> str = 'cpe:2.3:a:microsoft:internet_explorer:8.0.6001:beta:*:*:*:*:*:*' 11 | >>> c = CPE2_3_FS(str) 12 | >>> att = CPEComponentSimple.ATT_VENDOR 13 | >>> c.get_attribute_values(att) 14 | ['microsoft'] 15 | >>> att = CPEComponentSimple.ATT_VERSION 16 | >>> c.get_attribute_values(att) 17 | ['8.0.6001'] 18 | 19 | 20 | ----------------------------------------------- 21 | Test for __getitem__(self, i) 22 | ----------------------------------------------- 23 | 24 | - TEST: good index 25 | >>> str = 'cpe:2.3:a:microsoft:internet_explorer:8.*:sp?:*:*:*:*:*:*' 26 | >>> c = CPE2_3_FS(str) 27 | >>> c[1] 28 | CPEComponent2_3_FS(microsoft) 29 | 30 | - TEST: bad index 31 | >>> str = 'cpe:2.3:a:microsoft:internet_explorer:8.\*:sp?:*:*:*:*:*:*' 32 | >>> c = CPE2_3_FS(str) 33 | >>> c[14] #doctest: +IGNORE_EXCEPTION_DETAIL 34 | Traceback (most recent call last): 35 | IndexError: Component index of CPE name out of range 36 | 37 | 38 | ----------------------------------------------- 39 | Test for __new__(cls, cpe_str, *args, **kwargs) 40 | ----------------------------------------------- 41 | 42 | - TEST: bad WFN 43 | >>> fs = 'baduri' 44 | >>> c = CPE2_3_FS(fs) #doctest: +IGNORE_EXCEPTION_DETAIL 45 | Traceback (most recent call last): 46 | ValueError: Malformed CPE name: validation of parts failed 47 | 48 | - TEST: an empty CPE. 49 | >>> fs = 'cpe:2.3:*:*:*:*:*:*:*:*:*:*:*' 50 | >>> c = CPE2_3_FS(fs) 51 | 52 | - TEST: an operating system CPE 53 | >>> fs = 'cpe:2.3:o:acme:producto:1.0:update2:pro:en-us:*:*:*:*' 54 | >>> c = CPE2_3_FS(fs) 55 | 56 | - TEST: an application CPE 57 | >>> fs = 'cpe:2.3:a:hp:insight_diagnostics:7.4.0.1570:-:online:-:windows_2003:x64:*:*' 58 | >>> c = CPE2_3_FS(fs) 59 | 60 | - TEST: an application CPE 61 | >>> fs = 'cpe:2.3:a:hp:insight_diagnostics:8.*:es?:*:-:-:x32:*:*' 62 | >>> c = CPE2_3_FS(fs) 63 | 64 | - TEST: an CPE with special characters 65 | >>> fs = 'cpe:2.3:a:hp:insight_diagnostics:8.*:es?:*:-:-:x32\~:*:*' 66 | >>> c = CPE2_3_FS(fs) 67 | 68 | - TEST: An unquoted question mark MAY be used at the beginning 69 | and/or the end of an attribute-value string 70 | >>> fs = 'cpe:2.3:a:hp:insight_diagnostics:*8.*:?es?:*:-:-:x32\~:*:*' 71 | >>> c = CPE2_3_FS(fs) 72 | 73 | - TEST: A contiguous sequence of unquoted question marks MAY appear at the 74 | beginning and/or the end of an attribute-value string 75 | >>> fs = 'cpe:2.3:a:???hp**:insight_diagnostics:8.*:es:*:-:-:x32\~:*:*' 76 | >>> c = CPE2_3_FS(fs) #doctest: +IGNORE_EXCEPTION_DETAIL 77 | Traceback (most recent call last): 78 | ValueError: Malformed CPE, vendor value is invalid 79 | 80 | - TEST: A contiguous sequence of unquoted question marks MAY appear at the 81 | beginning and/or the end of an attribute-value string 82 | >>> fs = 'cpe:2.3:a:???hp*:insight_diagnostics:8.*:es:*:-:-:x32\~:*:*' 83 | >>> c = CPE2_3_FS(fs) 84 | 85 | - TEST: Unquoted question marks and asterisks MAY appear 86 | in the same attribute-value string 87 | >>> fs = 'cpe:2.3:a:hp:insight_?diagnostics:8.*:es:*:-:-:x32\~:*:*' 88 | >>> c = CPE2_3_FS(fs) #doctest: +IGNORE_EXCEPTION_DETAIL 89 | Traceback (most recent call last): 90 | ValueError: Malformed CPE, product value is invalid 91 | 92 | - TEST: An unquoted question mark SHALL NOT be used 93 | in any other place in an attribute-value string 94 | >>> uri = 'cpe:2.3:h:?*nvidia:*:*:*:*:*:*:*:*:*' 95 | >>> c = CPE2_3_FS(uri) #doctest: +IGNORE_EXCEPTION_DETAIL 96 | Traceback (most recent call last): 97 | ValueError: Malformed CPE, vendor value is invalid 98 | 99 | 100 | ---------------------------------- 101 | Test for __len__(self) 102 | ---------------------------------- 103 | 104 | - TEST: a CPE name without components 105 | >>> str = "cpe:2.3:a:hp:openview_network_manager:7.51:*:*:*:*:linux:*:*" 106 | >>> c = CPE2_3_FS(str) 107 | >>> len(c) 108 | 11 109 | 110 | ---------------------------------- 111 | Test for __str__(self) 112 | ---------------------------------- 113 | 114 | TEST: not negate components 115 | >>> str = r'cpe:2.3:a:foo\\bar:big\$money_2010:*:*:*:*:special:ipod_touch:80gb:*' 116 | >>> c = CPE2_3_FS(str) 117 | >>> print(c) 118 | CPE v2.3 (FS): cpe:2.3:a:foo\\bar:big\$money_2010:*:*:*:*:special:ipod_touch:80gb:* 119 | 120 | 121 | ---------------------------------- 122 | Test for as_uri_2_3(self) 123 | ---------------------------------- 124 | 125 | - TEST: 126 | >>> fs1 = 'cpe:2.3:a:microsoft:internet_explorer:8.0.6001:beta:*:*:*:*:*:*' 127 | >>> c1 = CPE2_3_FS(fs1) 128 | >>> c1.as_uri_2_3() 129 | 'cpe:/a:microsoft:internet_explorer:8.0.6001:beta' 130 | 131 | 132 | ---------------------------------- 133 | Test for as_wfn(self) 134 | ---------------------------------- 135 | 136 | - TEST: 137 | >>> fs1 = 'cpe:2.3:a:microsoft:internet_explorer:8.0.6001:beta:*:*:*:*:*:*' 138 | >>> c1 = CPE2_3_FS(fs1) 139 | >>> c1.as_wfn() 140 | 'wfn:[part="a", vendor="microsoft", product="internet_explorer", version="8\\.0\\.6001", update="beta", edition=ANY, language=ANY, sw_edition=ANY, target_sw=ANY, target_hw=ANY, other=ANY]' 141 | 142 | - TEST: 143 | >>> fs2 = 'cpe:2.3:a:microsoft:internet_explorer:8.*:sp?:*:*:*:*:*:*' 144 | >>> c2 = CPE2_3_FS(fs2) 145 | >>> c2.as_wfn() 146 | 'wfn:[part="a", vendor="microsoft", product="internet_explorer", version="8\\.*", update="sp?", edition=ANY, language=ANY, sw_edition=ANY, target_sw=ANY, target_hw=ANY, other=ANY]' 147 | 148 | - TEST: 149 | >>> fs3 = 'cpe:2.3:a:hp:insight_diagnostics:7.4.0.1570:-:*:*:online:win2003:x64:*' 150 | >>> c3 = CPE2_3_FS(fs3) 151 | >>> c3.as_wfn() 152 | 'wfn:[part="a", vendor="hp", product="insight_diagnostics", version="7\\.4\\.0\\.1570", update=NA, edition=ANY, language=ANY, sw_edition="online", target_sw="win2003", target_hw="x64", other=ANY]' 153 | 154 | - TEST: 155 | >>> fs4 = r'cpe:2.3:a:foo\\bar:big\$money:2010:*:*:*:special:ipod_touch:80gb:*' 156 | >>> c4 = CPE2_3_FS(fs4) 157 | >>> c4.as_wfn() 158 | 'wfn:[part="a", vendor="foo\\\\bar", product="big\\$money", version="2010", update=ANY, edition=ANY, language=ANY, sw_edition="special", target_sw="ipod_touch", target_hw="80gb", other=ANY]' 159 | 160 | ---------------------------------- 161 | Test for as_fs(self) 162 | ---------------------------------- 163 | 164 | - TEST: 165 | >>> fs1 = 'cpe:2.3:a:microsoft:internet_explorer:8.0.6001:beta:*:*:*:*:*:*' 166 | >>> c1 = CPE2_3_FS(fs1) 167 | >>> c1.as_fs() 168 | 'cpe:2.3:a:microsoft:internet_explorer:8.0.6001:beta:*:*:*:*:*:*' 169 | -------------------------------------------------------------------------------- /tests/testfile_cpe2_3_uri.txt: -------------------------------------------------------------------------------- 1 | >>> from __future__ import print_function 2 | >>> from cpe.cpe2_3_uri import CPE2_3_URI 3 | >>> from cpe.comp.cpecomp_simple import CPEComponentSimple 4 | 5 | ---------------------------------- 6 | Test for _get_attribute_values(self) 7 | ---------------------------------- 8 | 9 | TEST: 10 | >>> str = 'cpe:/a:microsoft::8.%2a:sp%3f' 11 | >>> c = CPE2_3_URI(str) 12 | >>> att = CPEComponentSimple.ATT_VENDOR 13 | >>> c.get_attribute_values(att) 14 | ['microsoft'] 15 | >>> att = CPEComponentSimple.ATT_VERSION 16 | >>> c.get_attribute_values(att) # it is not wildcard 17 | ['8.%2a'] 18 | >>> att = CPEComponentSimple.ATT_UPDATE 19 | >>> c.get_attribute_values(att) # it is not wildcard 20 | ['sp%3f'] 21 | 22 | ----------------------------------------------- 23 | Test for __getitem__(self, i) 24 | ----------------------------------------------- 25 | 26 | - TEST: good index 27 | >>> str = 'cpe:/a:hp:insight_diagnostics:7.4.0.1570::~~online~win2003~x64~' 28 | >>> c = CPE2_3_URI(str) 29 | >>> c[2] 30 | CPEComponent2_3_URI(insight_diagnostics) 31 | 32 | - TEST: good index 33 | >>> str = 'cpe:/a:hp:insight_diagnostics:8::~~online~win2003~x64~' 34 | >>> c = CPE2_3_URI(str) 35 | >>> c[4] 36 | CPEComponentAnyValue() 37 | 38 | - TEST: good index 39 | >>> str = 'cpe:/a:hp:insight_diagnostics:7.4.0.1570::~~online~win2003~x64~' 40 | >>> c = CPE2_3_URI(str) 41 | >>> c[5] 42 | CPEComponent2_3_URI_edpacked(~~online~win2003~x64~) 43 | 44 | - TEST: bad index 45 | >>> str = 'cpe:/a:hp:insight_diagnostics:7.4.0.1570::~~online~win2003~x64~' 46 | >>> c = CPE2_3_URI(str) 47 | >>> c[14] #doctest: +IGNORE_EXCEPTION_DETAIL 48 | Traceback (most recent call last): 49 | IndexError: Component index of CPE name out of range 50 | 51 | 52 | ----------------------------------------------- 53 | Test for __new__(cls, cpe_str, *args, **kwargs) 54 | ----------------------------------------------- 55 | 56 | - TEST: bad URI 57 | >>> uri = 'baduri' 58 | >>> c = CPE2_3_URI(uri) #doctest: +IGNORE_EXCEPTION_DETAIL 59 | Traceback (most recent call last): 60 | ValueError: Malformed CPE name: validation of parts failed 61 | 62 | - TEST: URI with whitespaces 63 | >>> uri = 'cpe con espacios' 64 | >>> c = CPE2_3_URI(uri) #doctest: +IGNORE_EXCEPTION_DETAIL 65 | Traceback (most recent call last): 66 | ValueError: Malformed CPE name: it must not have whitespaces 67 | 68 | - TEST: an empty CPE. 69 | >>> uri = 'cpe:/' 70 | >>> c = CPE2_3_URI(uri) 71 | 72 | - TEST: an empty CPE with five parts 73 | >>> uri = 'cpe:/::::' 74 | >>> c = CPE2_3_URI(uri) 75 | 76 | - TEST: an empty CPE with bad part name 77 | >>> uri = 'cpe:/b::::' 78 | >>> c = CPE2_3_URI(uri) #doctest: +IGNORE_EXCEPTION_DETAIL 79 | Traceback (most recent call last): 80 | ValueError: Malformed CPE name: validation of parts failed 81 | 82 | - TEST: an CPE with too many components 83 | >>> uri = 'cpe:/a:1:2:3:4:5:6:7' 84 | >>> c = CPE2_3_URI(uri) #doctest: +IGNORE_EXCEPTION_DETAIL 85 | Traceback (most recent call last): 86 | ValueError: Malformed CPE name: validation of parts failed 87 | 88 | - TEST: an application CPE 89 | >>> uri = 'cpe:/a:acme:product:1.0:update2:pro:en-us' 90 | >>> c = CPE2_3_URI(uri) 91 | 92 | - TEST: an operating system CPE 93 | >>> uri = 'cpe:/o:microsoft:windows_xp:::pro' 94 | >>> c = CPE2_3_URI(uri) 95 | 96 | - TEST: an hardware CPE 97 | >>> uri = 'cpe:/h:nvidia' 98 | >>> c = CPE2_3_URI(uri) 99 | 100 | - TEST: An unquoted question mark MAY be used at the beginning of 101 | an attribute-value string 102 | >>> uri = 'cpe:/h:%3Fnvidia' 103 | >>> c = CPE2_3_URI(uri) 104 | 105 | - TEST: An unquoted question mark MAY be used at the end of 106 | an attribute-value string 107 | >>> uri = 'cpe:/h:nvidia%3F' 108 | >>> c = CPE2_3_URI(uri) 109 | 110 | - TEST: An unquoted question mark MAY be used at the beginning 111 | and/or the end of an attribute-value string 112 | >>> uri = 'cpe:/h:%3Fnvidia%3F' 113 | >>> c = CPE2_3_URI(uri) 114 | 115 | - TEST: A contiguous sequence of unquoted question marks MAY appear 116 | at the beginning and/or the end of an attribute-value string 117 | >>> uri = 'cpe:/h:%3F%3Fnvidia%3F%3F' 118 | >>> c = CPE2_3_URI(uri) 119 | 120 | - TEST: an CPE with special characters 121 | >>> uri = 'cpe:/h:nvidia.buena_2??pero_rara:11.0' 122 | >>> c = CPE2_3_URI(uri) #doctest: +IGNORE_EXCEPTION_DETAIL 123 | Traceback (most recent call last): 124 | ValueError: Malformed CPE name: not correct value 'nvidia.buena_2??pero_rara' 125 | 126 | - TEST: 127 | >>> uri = 'cpe:/a:foo~bar:big%7emoney_2010' 128 | >>> c = CPE2_3_URI(uri) #doctest: +IGNORE_EXCEPTION_DETAIL 129 | Traceback (most recent call last): 130 | ValueError: Malformed CPE name: not correct value 'foo~bar' 131 | 132 | ---------------------------------- 133 | Test for __len__(self) 134 | ---------------------------------- 135 | 136 | - TEST: a CPE name without components 137 | >>> str = "cpe:/a:hp:insight_diagnostics:7.4.0.1570::~~online~win2003~x64~" 138 | >>> c = CPE2_3_URI(str) 139 | >>> len(c) 140 | 6 141 | 142 | ---------------------------------- 143 | Test for __str__(self) 144 | ---------------------------------- 145 | 146 | TEST: not negate components 147 | >>> str = 'cpe:/a:hp:insight_diagnostics:7.4.0.1570::~~online~win2003~x64~' 148 | >>> c = CPE2_3_URI(str) 149 | >>> print(c) 150 | CPE v2.3 (URI): cpe:/a:hp:insight_diagnostics:7.4.0.1570::~~online~win2003~x64~ 151 | 152 | 153 | ---------------------------------- 154 | Test for as_uri_2_3(self) 155 | ---------------------------------- 156 | 157 | - TEST: 158 | >>> uri = 'cpe:/a:hp:openview_network_manager:7.51:-:~~~linux~~' 159 | >>> c1 = CPE2_3_URI(uri) 160 | >>> c1.as_uri_2_3() 161 | 'cpe:/a:hp:openview_network_manager:7.51:-:~~~linux~~' 162 | 163 | 164 | ---------------------------------- 165 | Test for as_wfn(self) 166 | ---------------------------------- 167 | 168 | - TEST: 169 | >>> uri = 'cpe:/a:hp:openview_network_manager:7.51:-:~~~linux~~' 170 | >>> c1 = CPE2_3_URI(uri) 171 | >>> c1.as_wfn() 172 | 'wfn:[part="a", vendor="hp", product="openview_network_manager", version="7\\.51", update=NA, edition=ANY, sw_edition=ANY, target_sw="linux", target_hw=ANY, other=ANY]' 173 | 174 | - TEST: 175 | >>> uri = 'cpe:/a:hp:insight_diagnostics:7.4.0.1570::~~online~win2003~x64~' 176 | >>> c3 = CPE2_3_URI(uri) 177 | >>> c3.as_wfn() 178 | 'wfn:[part="a", vendor="hp", product="insight_diagnostics", version="7\\.4\\.0\\.1570", update=ANY, edition=ANY, sw_edition="online", target_sw="win2003", target_hw="x64", other=ANY]' 179 | 180 | 181 | ---------------------------------- 182 | Test for as_fs(self) 183 | ---------------------------------- 184 | 185 | - TEST: 186 | >>> uri = 'cpe:/a:hp:openview_network_manager:7.51:-:~~~linux~~' 187 | >>> c1 = CPE2_3_URI(uri) 188 | >>> c1.as_fs() 189 | 'cpe:2.3:a:hp:openview_network_manager:7.51:-:*:*:*:linux:*:*' 190 | -------------------------------------------------------------------------------- /tests/testfile_cpe2_3_wfn.txt: -------------------------------------------------------------------------------- 1 | >>> from __future__ import print_function 2 | >>> from cpe.cpe2_3_wfn import CPE2_3_WFN 3 | >>> from cpe.comp.cpecomp_simple import CPEComponentSimple 4 | 5 | ---------------------------------- 6 | Test for _get_attribute_values(self) 7 | ---------------------------------- 8 | 9 | TEST: 10 | >>> str = r'wfn:[part="a", vendor="microsoft", product="internet_explorer", version="8\.0\.6001", update="beta", edition=ANY, language=ANY, sw_edition=ANY, target_sw=ANY, target_hw=ANY, other=ANY]' 11 | >>> c = CPE2_3_WFN(str) 12 | >>> att = CPEComponentSimple.ATT_VENDOR 13 | >>> c.get_attribute_values(att) 14 | ['"microsoft"'] 15 | >>> att = CPEComponentSimple.ATT_VERSION 16 | >>> c.get_attribute_values(att) 17 | ['"8\\.0\\.6001"'] 18 | 19 | 20 | ----------------------------------------------- 21 | Test for __getitem__(self, i) 22 | ----------------------------------------------- 23 | 24 | - TEST: good index 25 | >>> str = r'wfn:[part="a", vendor="microsoft", product="internet_explorer", version="8\.0\.6001", update="beta", edition=ANY, language=ANY, sw_edition=ANY, target_sw=ANY, target_hw=ANY, other=ANY]' 26 | >>> c = CPE2_3_WFN(str) 27 | >>> c[2] 28 | CPEComponent2_3_WFN("internet_explorer") 29 | 30 | - TEST: bad index 31 | >>> str = r'wfn:[part="a", vendor="foo\\bar", product="big\$money", version="2010", update=ANY, edition=ANY, language=ANY, sw_edition="special", target_sw="ipod_touch", target_hw="80gb", other=ANY]' 32 | >>> c = CPE2_3_WFN(str) 33 | >>> c[14] #doctest: +IGNORE_EXCEPTION_DETAIL 34 | Traceback (most recent call last): 35 | IndexError: Component index of CPE name out of range 36 | 37 | 38 | ----------------------------------------------- 39 | Test for __new__(cls, cpe_str, *args, **kwargs) 40 | ----------------------------------------------- 41 | 42 | - TEST: bad WFN 43 | >>> wfn = 'baduri' 44 | >>> c = CPE2_3_WFN(wfn) #doctest: +IGNORE_EXCEPTION_DETAIL 45 | Traceback (most recent call last): 46 | ValueError: Malformed CPE name: WFN prefix not found 47 | 48 | - TEST: an empty CPE. 49 | >>> wfn = 'wfn:[]' 50 | >>> c = CPE2_3_WFN(wfn) 51 | 52 | - TEST: an empty CPE with bad part name 53 | >>> wfn = 'wfn:[bad="hw"]' 54 | >>> c = CPE2_3_WFN(wfn) #doctest: +IGNORE_EXCEPTION_DETAIL 55 | Traceback (most recent call last): 56 | ValueError: Malformed CPE name: invalid attribute name 'bad' 57 | 58 | - TEST: an operating system CPE 59 | >>> wfn = r'wfn:[part="o", vendor="acme", product="producto", version="1\.0", update="update2", edition="pro", language="en\-us"]' 60 | >>> c = CPE2_3_WFN(wfn) 61 | 62 | - TEST: an application CPE 63 | >>> wfn = r'wfn:[part="a", vendor="hp", product="insight_diagnostics", version="7\.444\.0\.1570", sw_edition="online", target_sw="windows_2003", target_hw="x64", language=ANY, other=NA]' 64 | >>> c = CPE2_3_WFN(wfn) 65 | 66 | - TEST: an application CPE 67 | >>> wfn = r'wfn:[part="a", vendor="hp", product="insight_diagnostics", version="8\.*", sw_edition="?", target_sw=ANY, target_hw="x32"]' 68 | >>> c = CPE2_3_WFN(wfn) 69 | 70 | - TEST: an CPE with special characters 71 | >>> wfn = r'wfn:[part="h", vendor="hp", product="insight\diagnostics", version="8.0~"]' 72 | >>> c = CPE2_3_WFN(wfn) #doctest: +IGNORE_EXCEPTION_DETAIL 73 | Traceback (most recent call last): 74 | ValueError: Invalid value of attribute 'product': insight\_diagnostics 75 | 76 | - TEST: An unquoted question mark MAY be used at the beginning 77 | and/or the end of an attribute-value string 78 | >>> wfn = r'wfn:[part="a", vendor="hp", product="?insight_diagnostics?", version="8\.*", sw_edition="?", target_sw=ANY, target_hw="x32"]' 79 | >>> c = CPE2_3_WFN(wfn) 80 | 81 | - TEST: A contiguous sequence of unquoted question marks MAY appear 82 | at the beginning and/or the end of an attribute-value string 83 | >>> wfn = r'wfn:[part="a", vendor="???hp???", product="?insight_diagnostics?", version="8\.*", sw_edition="?", target_sw=ANY, target_hw="x32"]' 84 | >>> c = CPE2_3_WFN(wfn) 85 | 86 | - TEST: Unquoted question marks and asterisks MAY appear 87 | in the same attribute-value string 88 | >>> wfn = r'wfn:[part="a", vendor="???hp*", product="?insight_diagnostics?", version="8\.*", sw_edition="?", target_sw=ANY, target_hw="x32"]' 89 | >>> c = CPE2_3_WFN(wfn) 90 | 91 | - TEST: An unquoted question mark SHALL NOT be used 92 | in any other place in an attribute-value string 93 | >>> wfn = r'wfn:[part="a", vendor="h??p", product="?insight_diagnostics?", version="8\.*", sw_edition="?", target_sw=ANY, target_hw="x32"]' 94 | >>> c = CPE2_3_WFN(wfn) #doctest: +IGNORE_EXCEPTION_DETAIL 95 | Traceback (most recent call last): 96 | ValueError: Invalid value of attribute 'vendor': h??p 97 | 98 | 99 | ---------------------------------- 100 | Test for __len__(self) 101 | ---------------------------------- 102 | 103 | - TEST: a CPE name without components 104 | >>> str = r'wfn:[part="a", vendor="hp", product="?insight_diagnostics?", version="8\.*", sw_edition="?", target_sw=ANY, target_hw="x32"]' 105 | >>> c = CPE2_3_WFN(str) 106 | >>> len(c) 107 | 7 108 | 109 | - TEST: an empty CPE. 110 | >>> str = 'wfn:[]' 111 | >>> c = CPE2_3_WFN(str) 112 | >>> len(c) 113 | 0 114 | 115 | 116 | ---------------------------------- 117 | Test for __str__(self) 118 | ---------------------------------- 119 | 120 | TEST: not negate components 121 | >>> str = r'wfn:[part="a", vendor="hp", product="?insight_diagnostics?", version="8\.*", sw_edition="?", target_sw=ANY, target_hw="x32"]' 122 | >>> c = CPE2_3_WFN(str) 123 | >>> print(c) 124 | CPE v2.3 (WFN): wfn:[part="a", vendor="hp", product="?insight_diagnostics?", version="8\.*", sw_edition="?", target_sw=ANY, target_hw="x32"] 125 | 126 | 127 | ---------------------------------- 128 | Test for as_uri_2_3(self) 129 | ---------------------------------- 130 | 131 | - TEST: 132 | >>> str = 'wfn:[part="a", vendor="hp", product="?insight_diagnostics?", version="8\.*", sw_edition="?", target_sw=ANY, target_hw="x32"]' 133 | >>> c1 = CPE2_3_WFN(str) 134 | >>> c1.as_uri_2_3() 135 | 'cpe:/a:hp:%01insight_diagnostics%01:8.%02::~~%01~~x32~' 136 | 137 | 138 | ---------------------------------- 139 | Test for as_wfn(self) 140 | ---------------------------------- 141 | 142 | - TEST: 143 | >>> str = r'wfn:[part="a", vendor="microsoft", product="internet_explorer", version="8\.0\.6001", update="beta", edition=ANY, language=ANY, sw_edition=ANY, target_sw=ANY, target_hw=ANY, other=ANY]' 144 | >>> c1 = CPE2_3_WFN(str) 145 | >>> c1.as_wfn() 146 | 'wfn:[part="a", vendor="microsoft", product="internet_explorer", version="8\\.0\\.6001", update="beta", edition=ANY, language=ANY, sw_edition=ANY, target_sw=ANY, target_hw=ANY, other=ANY]' 147 | 148 | 149 | ---------------------------------- 150 | Test for as_fs(self) 151 | ---------------------------------- 152 | 153 | - TEST: 154 | >>> str = 'wfn:[part="a", vendor="microsoft", product="internet_explorer", version="8\\.0\\.6001", update="beta", edition=ANY, language=ANY, sw_edition=ANY, target_sw=ANY, target_hw=ANY, other=ANY]' 155 | >>> c = CPE2_3_WFN(str) 156 | >>> c.as_fs() 157 | 'cpe:2.3:a:microsoft:internet_explorer:8.0.6001:beta:*:*:*:*:*:*' 158 | -------------------------------------------------------------------------------- /tests/testfile_cpecomp.txt: -------------------------------------------------------------------------------- 1 | >>> from cpe.comp.cpecomp import CPEComponent 2 | 3 | ------------------------------------------- 4 | Test for is_valid_attribute(cls, att_name) 5 | ------------------------------------------- 6 | 7 | TEST: a right attribute 8 | >>> att = CPEComponent.ATT_PRODUCT 9 | >>> CPEComponent.is_valid_attribute(att) 10 | True 11 | 12 | TEST: a wrong attribute 13 | >>> att = "n@nexist" 14 | >>> CPEComponent.is_valid_attribute(att) 15 | False 16 | 17 | 18 | ------------------------------------------- 19 | Test for __init__(self, comp_str) 20 | ------------------------------------------- 21 | 22 | TEST: a right attribute 23 | >>> value = "example" 24 | >>> c = CPEComponent(att) 25 | 26 | 27 | ------------------------------------------- 28 | Test for __eq__(self, comp_str) 29 | ------------------------------------------- 30 | 31 | TEST: two equal components 32 | >>> value = "microsoft" 33 | >>> c = CPEComponent(value) 34 | >>> c == c 35 | True 36 | 37 | 38 | TEST: two equal components 39 | >>> value = "microsoft" 40 | >>> c = CPEComponent(value) 41 | >>> c2 = CPEComponent(value) 42 | >>> c == c2 43 | True 44 | 45 | 46 | TEST: two not equal components 47 | >>> value = "microsoft" 48 | >>> c = CPEComponent(value) 49 | >>> value2 = "linux" 50 | >>> c2 = CPEComponent(value2) 51 | >>> c == c2 52 | False 53 | 54 | 55 | ------------------------------------------- 56 | Test for __ne__(self, comp_str) 57 | ------------------------------------------- 58 | 59 | TEST: two equal components 60 | >>> value = "microsoft" 61 | >>> c = CPEComponent(value) 62 | >>> c != c 63 | False 64 | 65 | 66 | TEST: two equal components 67 | >>> value = "microsoft" 68 | >>> c = CPEComponent(value) 69 | >>> c2 = CPEComponent(value) 70 | >>> c != c2 71 | False 72 | 73 | 74 | TEST: two not equal components 75 | >>> value = "microsoft" 76 | >>> c = CPEComponent(value) 77 | >>> value2 = "linux" 78 | >>> c2 = CPEComponent(value2) 79 | >>> c != c2 80 | True 81 | -------------------------------------------------------------------------------- /tests/testfile_cpecomp_anyvalue.txt: -------------------------------------------------------------------------------- 1 | >>> from __future__ import print_function 2 | >>> from cpe.comp.cpecomp import CPEComponent 3 | >>> from cpe.comp.cpecomp_anyvalue import CPEComponentAnyValue 4 | 5 | ------------------------------------------- 6 | Test for __init__(self, comp_str) 7 | ------------------------------------------- 8 | 9 | TEST: 10 | >>> c = CPEComponentAnyValue() 11 | 12 | 13 | ------------------------------------------- 14 | Test for __eq__(self, comp_str) 15 | ------------------------------------------- 16 | 17 | TEST: two equal components 18 | >>> c = CPEComponentAnyValue() 19 | >>> c == c 20 | True 21 | 22 | 23 | TEST: two equal components 24 | >>> value = "microsoft" 25 | >>> c = CPEComponent(value) 26 | >>> c2 = CPEComponentAnyValue() 27 | >>> c == c2 28 | False 29 | 30 | 31 | ------------------------------------------- 32 | Test for __repr__(self, comp_str) 33 | ------------------------------------------- 34 | 35 | TEST: 36 | >>> c = CPEComponentAnyValue() 37 | >>> c 38 | CPEComponentAnyValue() 39 | 40 | 41 | ------------------------------------------- 42 | Test for __str__(self, comp_str) 43 | ------------------------------------------- 44 | 45 | TEST: 46 | >>> c = CPEComponentAnyValue() 47 | >>> print(c) 48 | 49 | -------------------------------------------------------------------------------- /tests/testfile_cpecomp_empty.txt: -------------------------------------------------------------------------------- 1 | >>> from __future__ import print_function 2 | >>> from cpe.comp.cpecomp import CPEComponent 3 | >>> from cpe.comp.cpecomp_empty import CPEComponentEmpty 4 | 5 | ------------------------------------------- 6 | Test for __init__(self, comp_str) 7 | ------------------------------------------- 8 | 9 | TEST: 10 | >>> c = CPEComponentEmpty() 11 | 12 | 13 | ------------------------------------------- 14 | Test for __eq__(self, comp_str) 15 | ------------------------------------------- 16 | 17 | TEST: two equal components 18 | >>> c = CPEComponentEmpty() 19 | >>> c == c 20 | True 21 | 22 | 23 | TEST: two equal components 24 | >>> value = "microsoft" 25 | >>> c = CPEComponent(value) 26 | >>> c2 = CPEComponentEmpty() 27 | >>> c == c2 28 | False 29 | 30 | 31 | ------------------------------------------- 32 | Test for __repr__(self, comp_str) 33 | ------------------------------------------- 34 | 35 | TEST: 36 | >>> c = CPEComponentEmpty() 37 | >>> c 38 | CPEComponentEmpty() 39 | 40 | 41 | ------------------------------------------- 42 | Test for __str__(self, comp_str) 43 | ------------------------------------------- 44 | 45 | TEST: 46 | >>> c = CPEComponentEmpty() 47 | >>> print(c) 48 | 49 | -------------------------------------------------------------------------------- /tests/testfile_cpecomp_logical.txt: -------------------------------------------------------------------------------- 1 | >>> from __future__ import print_function 2 | >>> from cpe.comp.cpecomp_logical import CPEComponentLogical 3 | >>> from cpe.comp.cpecomp_anyvalue import CPEComponentAnyValue 4 | >>> from cpe.comp.cpecomp_empty import CPEComponentEmpty 5 | >>> from cpe.comp.cpecomp_undefined import CPEComponentUndefined 6 | >>> from cpe.comp.cpecomp_notapplicable import CPEComponentNotApplicable 7 | 8 | ------------------------------------------- 9 | Test for __contains__(self, comp_str) 10 | ------------------------------------------- 11 | 12 | TEST: 13 | >>> a = CPEComponentAnyValue() 14 | >>> a in a 15 | True 16 | 17 | TEST: 18 | >>> u = CPEComponentUndefined() 19 | >>> a = CPEComponentAnyValue() 20 | >>> u in a 21 | True 22 | >>> a in u 23 | True 24 | 25 | TEST: 26 | >>> e = CPEComponentEmpty() 27 | >>> a = CPEComponentAnyValue() 28 | >>> e in a 29 | True 30 | >>> a in e 31 | True 32 | 33 | TEST: 34 | >>> n = CPEComponentNotApplicable() 35 | >>> a = CPEComponentAnyValue() 36 | >>> n in a 37 | True 38 | >>> a in n 39 | False 40 | 41 | ------------------------------------------- 42 | Test for __eq__(self, comp_str) 43 | ------------------------------------------- 44 | 45 | TEST: two equal components 46 | >>> c = CPEComponentLogical(1) 47 | >>> c == c #doctest: +IGNORE_EXCEPTION_DETAIL 48 | Traceback (most recent call last): 49 | NotImplementedError: Class method not implemented. Use the method of some child class 50 | 51 | 52 | ------------------------------------------- 53 | Test for __repr__(self, comp_str) 54 | ------------------------------------------- 55 | 56 | TEST: 57 | >>> c = CPEComponentLogical(1) 58 | >>> c 59 | CPEComponentLogical() 60 | 61 | 62 | ------------------------------------------- 63 | Test for __str__(self, comp_str) 64 | ------------------------------------------- 65 | 66 | TEST: 67 | >>> c = CPEComponentLogical(1) 68 | >>> print(c) #doctest: +IGNORE_EXCEPTION_DETAIL 69 | Traceback (most recent call last): 70 | NotImplementedError: Class method not implemented. Use the method of some child class 71 | -------------------------------------------------------------------------------- /tests/testfile_cpecomp_notapplicable.txt: -------------------------------------------------------------------------------- 1 | >>> from __future__ import print_function 2 | >>> from cpe.comp.cpecomp import CPEComponent 3 | >>> from cpe.comp.cpecomp_notapplicable import CPEComponentNotApplicable 4 | 5 | ------------------------------------------- 6 | Test for __contains__(self, comp_str) 7 | ------------------------------------------- 8 | 9 | TEST: 10 | >>> c = CPEComponentNotApplicable() 11 | >>> c in c 12 | True 13 | 14 | TEST: 15 | >>> value = "microsoft" 16 | >>> c = CPEComponent(value) 17 | >>> c2 = CPEComponentNotApplicable() 18 | >>> c in c2 19 | False 20 | >>> c2 in c 21 | False 22 | 23 | 24 | ------------------------------------------- 25 | Test for __eq__(self, comp_str) 26 | ------------------------------------------- 27 | 28 | TEST: two equal components 29 | >>> c = CPEComponentNotApplicable() 30 | >>> c == c 31 | True 32 | 33 | 34 | TEST: two not equal components 35 | >>> value = "microsoft" 36 | >>> c = CPEComponent(value) 37 | >>> c2 = CPEComponentNotApplicable() 38 | >>> c == c2 39 | False 40 | 41 | 42 | ------------------------------------------- 43 | Test for __init__(self, comp_str) 44 | ------------------------------------------- 45 | 46 | TEST: 47 | >>> c = CPEComponentNotApplicable() 48 | 49 | 50 | ------------------------------------------- 51 | Test for __repr__(self, comp_str) 52 | ------------------------------------------- 53 | 54 | TEST: 55 | >>> c = CPEComponentNotApplicable() 56 | >>> c 57 | CPEComponentNotApplicable() 58 | 59 | 60 | ------------------------------------------- 61 | Test for __str__(self, comp_str) 62 | ------------------------------------------- 63 | 64 | TEST: 65 | >>> c = CPEComponentNotApplicable() 66 | >>> print(c) 67 | 68 | -------------------------------------------------------------------------------- /tests/testfile_cpecomp_simple.txt: -------------------------------------------------------------------------------- 1 | >>> from cpe.comp.cpecomp import CPEComponent 2 | >>> from cpe.comp.cpecomp_simple import CPEComponentSimple 3 | 4 | ---------------------------------- 5 | Test for _is_alphanum(cls, c) 6 | ---------------------------------- 7 | 8 | TEST: a lower letter 9 | >>> c = "j" 10 | >>> CPEComponentSimple._is_alphanum(c) 11 | True 12 | 13 | TEST: a upper letter 14 | >>> c = "A" 15 | >>> CPEComponentSimple._is_alphanum(c) 16 | True 17 | 18 | TEST: a number 19 | >>> c = "9" 20 | >>> CPEComponentSimple._is_alphanum(c) 21 | True 22 | 23 | TEST: a underscore 24 | >>> c = "_" 25 | >>> CPEComponentSimple._is_alphanum(c) 26 | True 27 | 28 | TEST: a wrong character 29 | >>> c = "#" 30 | >>> CPEComponentSimple._is_alphanum(c) 31 | False 32 | 33 | 34 | ------------------------------------------- 35 | Test for _pct_encode_uri(cls, c) 36 | ------------------------------------------- 37 | 38 | TEST: 39 | >>> c = '-' 40 | >>> CPEComponentSimple._pct_encode_uri(c) 41 | '-' 42 | 43 | TEST: 44 | >>> c = '.' 45 | >>> CPEComponentSimple._pct_encode_uri(c) 46 | '.' 47 | 48 | TEST: 49 | >>> c = ';' 50 | >>> CPEComponentSimple._pct_encode_uri(c) 51 | '%3b' 52 | 53 | ------------------------------------------- 54 | Test for __init__(self, comp_str) 55 | ------------------------------------------- 56 | 57 | TEST: 58 | >>> value = "linux" 59 | >>> att = CPEComponent.ATT_PRODUCT 60 | >>> c = CPEComponentSimple(value, att) #doctest: +IGNORE_EXCEPTION_DETAIL 61 | Traceback (most recent call last): 62 | NotImplementedError: Class method not implemented. Use the method of some child class 63 | -------------------------------------------------------------------------------- /tests/testfile_cpecomp_undefined.txt: -------------------------------------------------------------------------------- 1 | >>> from __future__ import print_function 2 | >>> from cpe.comp.cpecomp import CPEComponent 3 | >>> from cpe.comp.cpecomp_undefined import CPEComponentUndefined 4 | 5 | ------------------------------------------- 6 | Test for __init__(self, comp_str) 7 | ------------------------------------------- 8 | 9 | TEST: 10 | >>> c = CPEComponentUndefined() 11 | 12 | 13 | ------------------------------------------- 14 | Test for __eq__(self, comp_str) 15 | ------------------------------------------- 16 | 17 | TEST: two equal components 18 | >>> c = CPEComponentUndefined() 19 | >>> c == c 20 | True 21 | 22 | 23 | TEST: two equal components 24 | >>> value = "microsoft" 25 | >>> c = CPEComponent(value) 26 | >>> c2 = CPEComponentUndefined() 27 | >>> c == c2 28 | False 29 | 30 | 31 | ------------------------------------------- 32 | Test for __repr__(self, comp_str) 33 | ------------------------------------------- 34 | 35 | TEST: 36 | >>> c = CPEComponentUndefined() 37 | >>> c 38 | CPEComponentUndefined() 39 | 40 | 41 | ------------------------------------------- 42 | Test for __str__(self, comp_str) 43 | ------------------------------------------- 44 | 45 | TEST: 46 | >>> c = CPEComponentUndefined() 47 | >>> print(c) 48 | 49 | -------------------------------------------------------------------------------- /tests/testfile_cpelang2_2.txt: -------------------------------------------------------------------------------- 1 | >>> from cpe.cpe2_2 import CPE2_2 2 | >>> from cpe.cpeset2_2 import CPESet2_2 3 | >>> from cpe.cpelang2_2 import CPELanguage2_2 4 | 5 | ----------------------------------------------------- 6 | Test for __init__(self, expression, isFile=False) 7 | ----------------------------------------------------- 8 | 9 | - TEST: matching with no file 10 | >>> document = '''Sun Solaris 5.8 or 5.9 with BEA Weblogic 8.1 installed''' 11 | 12 | >>> c1 = CPE2_2('cpe:/o:sun:solaris:5.9:::en-us') 13 | >>> c2 = CPE2_2('cpe:/a:bea:weblogic:8.1') 14 | 15 | >>> s = CPESet2_2() 16 | >>> s.append(c1) 17 | >>> s.append(c2) 18 | 19 | >>> l = CPELanguage2_2(document) 20 | 21 | - TEST: matching with XML file 22 | >>> document = "tests/expression2_2.xml" 23 | 24 | >>> c1 = CPE2_2('cpe:/o:sun:solaris:5.9:::en-us') 25 | >>> c2 = CPE2_2('cpe:/a:bea:weblogic:8.1') 26 | 27 | >>> s = CPESet2_2() 28 | >>> s.append(c1) 29 | >>> s.append(c2) 30 | 31 | >>> isFile = True 32 | >>> l = CPELanguage2_2(document, isFile) 33 | 34 | 35 | ----------------------------------------------------- 36 | Test for language_match(self, cpeset, cpel_dom=None) 37 | ----------------------------------------------------- 38 | 39 | - TEST: matching 40 | >>> document = '''Sun Solaris 5.8 or 5.9 with BEA Weblogic 8.1 installed''' 41 | 42 | >>> c1 = CPE2_2('cpe:/o:sun:solaris:5.9:::en-us') 43 | >>> c2 = CPE2_2('cpe:/a:bea:weblogic:8.1') 44 | 45 | >>> s = CPESet2_2() 46 | >>> s.append(c1) 47 | >>> s.append(c2) 48 | 49 | >>> l = CPELanguage2_2(document) 50 | >>> l.language_match(s) 51 | True 52 | 53 | - TEST: matching 54 | >>> document = '''Windows with secedit.exe tool ''' 55 | 56 | >>> c1 = CPE2_2('cpe:/o:microsoft:windows_2000::pro') 57 | >>> c2 = CPE2_2('cpe:/a:microsoft:office:2007') 58 | >>> c3 = CPE2_2('cpe:/o:sun:solaris:5') 59 | 60 | >>> s = CPESet2_2() 61 | >>> s.append(c1) 62 | >>> s.append(c2) 63 | >>> s.append(c3) 64 | 65 | >>> l = CPELanguage2_2(document) 66 | >>> l.language_match(s) 67 | True 68 | 69 | - TEST: matching (negate) 70 | >>> document = '''Windows with secedit.exe tool ''' 71 | 72 | >>> c1 = CPE2_2('cpe:/o:microsoft:windows_2000::pro') 73 | >>> c2 = CPE2_2('cpe:/a:microsoft:office:2007') 74 | >>> c3 = CPE2_2('cpe:/o:sun:solaris:5') 75 | 76 | >>> s = CPESet2_2() 77 | >>> s.append(c1) 78 | >>> s.append(c2) 79 | >>> s.append(c3) 80 | 81 | >>> l = CPELanguage2_2(document) 82 | >>> l.language_match(s) 83 | True 84 | 85 | - TEST: not matching 86 | >>> document = '''Windows with secedit.exe tool ''' 87 | 88 | >>> c1 = CPE2_2('cpe:/o:microsoft:windows_2000::pro') 89 | >>> c2 = CPE2_2('cpe:/a:microsoft:office:2007') 90 | >>> c3 = CPE2_2('cpe:/o:sun:solaris:5') 91 | 92 | >>> s = CPESet2_2() 93 | >>> s.append(c1) 94 | >>> s.append(c2) 95 | >>> s.append(c3) 96 | 97 | >>> l = CPELanguage2_2(document) 98 | >>> l.language_match(s) 99 | False 100 | -------------------------------------------------------------------------------- /tests/testfile_cpelang2_3.txt: -------------------------------------------------------------------------------- 1 | >>> from cpe.cpe2_3 import CPE2_3 2 | >>> from cpe.cpe2_3_fs import CPE2_3_FS 3 | >>> from cpe.cpe2_3_wfn import CPE2_3_WFN 4 | >>> from cpe.cpeset2_3 import CPESet2_3 5 | >>> from cpe.cpelang2_3 import CPELanguage2_3 6 | 7 | ----------------------------------------------------- 8 | Test for language_match(self, cpeset, cpel_dom=None) 9 | ----------------------------------------------------- 10 | 11 | - TEST: not matching (there are undefined values) 12 | >>> document = '''Sun Solaris 5.8 or 5.9 with BEA Weblogic 8.1 installed''' 13 | 14 | >>> c1 = CPE2_3_FS('cpe:2.3:o:sun:solaris:5.9:*:*:*:*:*:*:*') 15 | >>> c2 = CPE2_3_FS('cpe:2.3:a:bea:weblogic:8.*:*:*:*:*:*:*:*') 16 | 17 | >>> s = CPESet2_3() 18 | >>> s.append(c1) 19 | >>> s.append(c2) 20 | 21 | >>> l = CPELanguage2_3(document) 22 | >>> l.language_match(s) 23 | False 24 | 25 | - TEST: matching 26 | >>> document = '''Sun Solaris 5.8''' 27 | 28 | >>> c1 = CPE2_3_FS('cpe:2.3:o:sun:solaris:5.9:*:*:*:*:*:*:*') 29 | >>> c2 = CPE2_3_FS('cpe:2.3:a:bea:weblogic:8.1:*:*:*:*:*:*:*') 30 | 31 | >>> s = CPESet2_3() 32 | >>> s.append(c1) 33 | >>> s.append(c2) 34 | 35 | >>> l = CPELanguage2_3(document) 36 | >>> l.language_match(s) 37 | True 38 | 39 | 40 | - TEST: not matching 41 | >>> path = "tests/expression2_3.xml" 42 | 43 | >>> c1 = CPE2_3_FS('cpe:2.3:o:sun:solaris:5.9:*:*:*:*:*:*:*') 44 | >>> c2 = CPE2_3_FS('cpe:2.3:a:bea:weblogic:8.*:*:*:*:*:*:*:*') 45 | 46 | >>> s = CPESet2_3() 47 | >>> s.append(c1) 48 | >>> s.append(c2) 49 | 50 | >>> isFile = True 51 | >>> l = CPELanguage2_3(path, isFile) 52 | >>> l.language_match(s) 53 | False 54 | 55 | - TEST: not matching with JSON file 56 | >>> path = "tests/expression2_3.json" 57 | 58 | >>> c1 = CPE2_3_FS('cpe:2.3:o:sun:solaris:5.9:*:*:*:*:*:*:*') 59 | >>> c2 = CPE2_3_FS('cpe:2.3:a:bea:weblogic:8.*:*:*:*:*:*:*:*') 60 | 61 | >>> s = CPESet2_3() 62 | >>> s.append(c1) 63 | >>> s.append(c2) 64 | 65 | >>> isFile = True 66 | >>> isJSON = True 67 | >>> l = CPELanguage2_3(path, isFile, isJSON) 68 | >>> l.language_match(s) 69 | False 70 | 71 | - TEST: matching with JSON file 72 | >>> path = "tests/expression2_3.json" 73 | 74 | >>> c1 = CPE2_3_FS('cpe:2.3:o:sun:solaris:5.9:*:*:*:*:*:*:*') 75 | >>> c2 = CPE2_3_FS('cpe:2.3:a:bea:weblogic:8.1:*:*:*:*:*:*:*') 76 | 77 | >>> s = CPESet2_3() 78 | >>> s.append(c1) 79 | >>> s.append(c2) 80 | 81 | >>> isFile = True 82 | >>> isJSON = True 83 | >>> l = CPELanguage2_3(path, isFile, isJSON) 84 | >>> l.language_match(s) 85 | True 86 | 87 | ----------------------------------------------------- 88 | Test for _unbind(cls, boundname) 89 | ----------------------------------------------------- 90 | 91 | - TEST: Formatted string to WFN 92 | >>> fs = 'cpe:2.3:a:hp:insight_diagnostics:7.4.0.1570:-:*:*:online:win2003:x64:*' 93 | >>> c = CPELanguage2_3._unbind(fs) 94 | >>> wfn = 'wfn:[part="a", vendor="hp", product="insight_diagnostics", version="7\\.4\\.0\\.1570", update=NA, edition=ANY, language=ANY, sw_edition="online", target_sw="win2003", target_hw="x64", other=ANY]' 95 | >>> c2 = CPE2_3_WFN(wfn) 96 | >>> c == c2 97 | True 98 | 99 | 100 | - TEST: URI to WFN 101 | >>> uri = 'cpe:/a:hp:openview_network_manager:7.51:-:~~~linux~~' 102 | >>> c = CPELanguage2_3._unbind(uri) 103 | >>> wfn = 'wfn:[part="a", vendor="hp", product="openview_network_manager", version="7\\.51", update=NA, edition=ANY, language=ANY, sw_edition=ANY, target_sw="linux", target_hw=ANY, other=ANY]' 104 | >>> c2 = CPE2_3_WFN(wfn) 105 | >>> c == c2 106 | True 107 | -------------------------------------------------------------------------------- /tests/testfile_cpeset1_1.txt: -------------------------------------------------------------------------------- 1 | >>> from cpe.cpeset1_1 import CPESet1_1 2 | >>> from cpe.cpe1_1 import CPE1_1 3 | 4 | ----------------------------------------------- 5 | Test for __getitem__(self, i) 6 | ----------------------------------------------- 7 | 8 | - TEST: empty set 9 | >>> s = CPESet1_1() 10 | >>> s[0] # doctest: +IGNORE_EXCEPTION_DETAIL 11 | Traceback (most recent call last): 12 | IndexError: list index out of range 13 | 14 | - TEST: set with two CPE names 15 | >>> uri1 = 'cpe://microsoft:windows:xp!vista' 16 | >>> uri2 = 'cpe:/cisco::3825;cisco:2:44/cisco:ios:12.3:enterprise' 17 | >>> c1 = CPE1_1(uri1) 18 | >>> c2 = CPE1_1(uri2) 19 | >>> s = CPESet1_1() 20 | >>> s.append(c1) 21 | >>> s.append(c2) 22 | >>> c22 = s[1] 23 | >>> c22 == c2 24 | True 25 | >>> c22 == c1 26 | False 27 | 28 | ---------------------------------- 29 | Test for __len__(self) 30 | ---------------------------------- 31 | 32 | - TEST: empty set 33 | >>> s = CPESet1_1() 34 | >>> len(s) 35 | 0 36 | 37 | - TEST: set with two CPE names 38 | >>> uri1 = 'cpe://microsoft:windows:xp!vista' 39 | >>> uri2 = 'cpe:/cisco::3825;cisco:2:44/cisco:ios:12.3:enterprise' 40 | >>> c1 = CPE1_1(uri1) 41 | >>> c2 = CPE1_1(uri2) 42 | >>> s = CPESet1_1() 43 | >>> s.append(c1) 44 | >>> s.append(c2) 45 | >>> len(s) 46 | 2 47 | 48 | - TEST: set with three CPE names and one repeated 49 | >>> uri1 = 'cpe://microsoft:windows:xp!vista' 50 | >>> uri2 = 'cpe:/cisco::3825;cisco:2:44' 51 | >>> c1 = CPE1_1(uri1) 52 | >>> c2 = CPE1_1(uri2) 53 | >>> s = CPESet1_1() 54 | >>> s.append(c1) 55 | >>> s.append(c2) 56 | >>> s.append(c2) 57 | >>> len(s) 58 | 2 59 | 60 | - TEST: set with three CPE names and one repeated 61 | >>> uri1 = 'cpe://microsoft:windows:xp!vista' 62 | >>> uri2 = 'cpe:/cisco::3825;cisco:2:44' 63 | >>> c1 = CPE1_1(uri1) 64 | >>> c2 = CPE1_1(uri2) 65 | >>> c3 = CPE1_1(uri2) 66 | >>> s = CPESet1_1() 67 | >>> s.append(c1) 68 | >>> s.append(c2) 69 | >>> s.append(c3) 70 | >>> len(s) 71 | 2 72 | 73 | 74 | ---------------------------------- 75 | Test for append(self, cpe) 76 | ---------------------------------- 77 | 78 | - TEST: set with invalid CPE name 79 | >>> from cpe.cpe2_2 import CPE2_2 80 | >>> uri = 'cpe:/a:microsoft' 81 | >>> c = CPE2_2(uri) 82 | >>> s = CPESet1_1() 83 | >>> s.append(c) #doctest: +IGNORE_EXCEPTION_DETAIL 84 | Traceback (most recent call last): 85 | ValueError: CPE name version 2.2 not valid, version 1.1 expected 86 | 87 | ---------------------------------- 88 | Test for name_match(self, cpe): 89 | ---------------------------------- 90 | 91 | - TEST: matching with identical CPE in set 92 | >>> uri1 = 'cpe://microsoft:windows:xp!vista' 93 | >>> uri2 = 'cpe:/cisco::3825;cisco:2:44/cisco:ios:12.3:enterprise' 94 | >>> c1 = CPE1_1(uri1) 95 | >>> c2 = CPE1_1(uri2) 96 | >>> s = CPESet1_1() 97 | >>> s.append(c1) 98 | >>> s.append(c2) 99 | >>> s.name_match(c2) 100 | True 101 | 102 | - TEST: matching with ANY values implicit 103 | >>> uri1 = 'cpe://microsoft:windows:xp!vista' 104 | >>> uri2 = 'cpe:/cisco::3825;cisco:2:44/cisco:ios:12.3:enterprise' 105 | >>> c1 = CPE1_1(uri1) 106 | >>> c2 = CPE1_1(uri2) 107 | >>> s = CPESet1_1() 108 | >>> s.append(c1) 109 | >>> s.append(c2) 110 | >>> uri3 = 'cpe:/cisco' 111 | >>> c3 = CPE1_1(uri3) 112 | >>> s.name_match(c3) 113 | True 114 | 115 | - TEST: matching with empty CPE name 116 | >>> uri1 = 'cpe://microsoft:windows:xp!vista' 117 | >>> uri2 = 'cpe:/cisco::3825;cisco:2:44/cisco:ios:12.3:enterprise' 118 | >>> c1 = CPE1_1(uri1) 119 | >>> c2 = CPE1_1(uri2) 120 | >>> s = CPESet1_1() 121 | >>> s.append(c1) 122 | >>> s.append(c2) 123 | >>> uri3 = 'cpe:/' 124 | >>> c3 = CPE1_1(uri3) 125 | >>> s.name_match(c3) 126 | True 127 | 128 | - TEST: not matching with CPE name 129 | >>> uri1 = 'cpe://microsoft:windows:xp!vista' 130 | >>> uri2 = 'cpe:/cisco::3825;cisco:2:44/cisco:ios:12.3:enterprise' 131 | >>> c1 = CPE1_1(uri1) 132 | >>> c2 = CPE1_1(uri2) 133 | >>> s = CPESet1_1() 134 | >>> s.append(c1) 135 | >>> s.append(c2) 136 | >>> uri3 = 'cpe://noexists' 137 | >>> c3 = CPE1_1(uri3) 138 | >>> s.name_match(c3) 139 | False 140 | 141 | - TEST: matching with ANY values explicit 142 | >>> uri1 = 'cpe://microsoft:windows:xp!vista' 143 | >>> uri2 = 'cpe:/cisco::3825;cisco:2:44/cisco:ios:12.3:enterprise' 144 | >>> c1 = CPE1_1(uri1) 145 | >>> c2 = CPE1_1(uri2) 146 | >>> s = CPESet1_1() 147 | >>> s.append(c1) 148 | >>> s.append(c2) 149 | >>> uri3 = 'cpe://microsoft:::' 150 | >>> c3 = CPE1_1(uri3) 151 | >>> s.name_match(c3) 152 | True 153 | 154 | - TEST: matching with NOT 155 | >>> uri1 = 'cpe://microsoft:windows:~xp' 156 | >>> c1 = CPE1_1(uri1) 157 | >>> s = CPESet1_1() 158 | >>> s.append(c1) 159 | >>> uri2 = 'cpe://microsoft:windows:vista' 160 | >>> c2 = CPE1_1(uri2) 161 | >>> s.name_match(c2) 162 | False 163 | 164 | - TEST: matching with NOT 165 | >>> uri1 = 'cpe://microsoft:windows:xp' 166 | >>> c1 = CPE1_1(uri1) 167 | >>> s = CPESet1_1() 168 | >>> s.append(c1) 169 | >>> uri2 = 'cpe://microsoft:windows:~vista' 170 | >>> c2 = CPE1_1(uri2) 171 | >>> s.name_match(c2) 172 | True 173 | 174 | - TEST: matching with OR 175 | >>> uri1 = 'cpe:/cisco::3825;cisco:2:44/cisco:ios:12.3:enterprise' 176 | >>> uri2 = 'cpe://microsoft:windows:xp!vista' 177 | >>> c1 = CPE1_1(uri1) 178 | >>> c2 = CPE1_1(uri2) 179 | >>> s = CPESet1_1() 180 | >>> s.append(c1) 181 | >>> s.append(c2) 182 | >>> uri3 = 'cpe://microsoft:windows:vista' 183 | >>> c3 = CPE1_1(uri3) 184 | >>> s.name_match(c3) 185 | False 186 | 187 | - TEST: matching with OR 188 | >>> uri1 = 'cpe:/cisco::3825;cisco:2:44/cisco:ios:12.3:enterprise' 189 | >>> uri2 = 'cpe://microsoft:windows:vista' 190 | >>> c1 = CPE1_1(uri1) 191 | >>> c2 = CPE1_1(uri2) 192 | >>> s = CPESet1_1() 193 | >>> s.append(c1) 194 | >>> s.append(c2) 195 | >>> uri3 = 'cpe://microsoft:windows:xp!vista' 196 | >>> c3 = CPE1_1(uri3) 197 | >>> s.name_match(c3) 198 | True 199 | -------------------------------------------------------------------------------- /tests/testfile_cpeset2_2.txt: -------------------------------------------------------------------------------- 1 | >>> from cpe.cpeset2_2 import CPESet2_2 2 | >>> from cpe.cpe2_2 import CPE2_2 3 | 4 | ----------------------------------------------- 5 | Test for __getitem__(self, i) 6 | ----------------------------------------------- 7 | 8 | - TEST: empty set 9 | >>> s = CPESet2_2() 10 | >>> s[0] # doctest: +IGNORE_EXCEPTION_DETAIL 11 | Traceback (most recent call last): 12 | IndexError: list index out of range 13 | 14 | - TEST: set with two CPE names 15 | >>> uri1 = 'cpe:/a:acme:product:1.0:update2::en-us' 16 | >>> uri2 = 'cpe:/o:redhat:enterprise_linux:4:ga' 17 | >>> c1 = CPE2_2(uri1) 18 | >>> c2 = CPE2_2(uri2) 19 | >>> s = CPESet2_2() 20 | >>> s.append(c1) 21 | >>> s.append(c2) 22 | >>> c22 = s[1] 23 | >>> c22 == c2 24 | True 25 | >>> c22 == c1 26 | False 27 | 28 | ---------------------------------- 29 | Test for __len__(self) 30 | ---------------------------------- 31 | 32 | - TEST: empty set 33 | >>> s = CPESet2_2() 34 | >>> len(s) 35 | 0 36 | 37 | - TEST: set with two CPE names 38 | >>> uri1 = 'cpe:/a:acme:product:1.0:update2::en-us' 39 | >>> uri2 = 'cpe:/o:redhat:enterprise_linux:4:ga' 40 | >>> c1 = CPE2_2(uri1) 41 | >>> c2 = CPE2_2(uri2) 42 | >>> s = CPESet2_2() 43 | >>> s.append(c1) 44 | >>> s.append(c2) 45 | >>> len(s) 46 | 2 47 | 48 | - TEST: set with three CPE names and one repeated 49 | >>> uri1 = 'cpe:/a:acme:product:1.0:update2::en-us' 50 | >>> uri2 = 'cpe:/o:redhat:enterprise_linux:4:ga' 51 | >>> c1 = CPE2_2(uri1) 52 | >>> c2 = CPE2_2(uri2) 53 | >>> s = CPESet2_2() 54 | >>> s.append(c1) 55 | >>> s.append(c2) 56 | >>> s.append(c2) 57 | >>> len(s) 58 | 2 59 | 60 | - TEST: set with three CPE names and one repeated 61 | >>> uri1 = 'cpe:/a:acme:product:1.0:update2::en-us' 62 | >>> uri2 = 'cpe:/o:redhat:enterprise_linux:4:ga' 63 | >>> c1 = CPE2_2(uri1) 64 | >>> c2 = CPE2_2(uri2) 65 | >>> c3 = CPE2_2(uri2) 66 | >>> s = CPESet2_2() 67 | >>> s.append(c1) 68 | >>> s.append(c2) 69 | >>> s.append(c3) 70 | >>> len(s) 71 | 2 72 | 73 | 74 | ---------------------------------- 75 | Test for append(self, cpe) 76 | ---------------------------------- 77 | 78 | - TEST: set with invalid CPE name 79 | >>> from cpe.cpe1_1 import CPE1_1 80 | >>> uri = 'cpe://microsoft:windows:xp!vista' 81 | >>> c = CPE1_1(uri) 82 | >>> s = CPESet2_2() 83 | >>> s.append(c) #doctest: +IGNORE_EXCEPTION_DETAIL 84 | Traceback (most recent call last): 85 | ValueError: CPE name version 1.1 not valid, version 2.2 expected 86 | 87 | 88 | ---------------------------------- 89 | Test for name_match(self, cpe): 90 | ---------------------------------- 91 | 92 | - TEST: matching with identical CPE in set 93 | >>> uri1 = 'cpe:/o:microsoft:windows_2000::sp3:pro' 94 | >>> uri2 = 'cpe:/a:microsoft:ie:5.5' 95 | >>> c1 = CPE2_2(uri1) 96 | >>> c2 = CPE2_2(uri2) 97 | >>> s = CPESet2_2() 98 | >>> s.append(c1) 99 | >>> s.append(c2) 100 | >>> s.name_match(c2) 101 | True 102 | 103 | - TEST: matching with ANY values implicit 104 | >>> uri1 = 'cpe:/o:microsoft:windows_2000::sp3:pro' 105 | >>> uri2 = 'cpe:/a:microsoft:ie:5.5' 106 | >>> c1 = CPE2_2(uri1) 107 | >>> c2 = CPE2_2(uri2) 108 | >>> s = CPESet2_2() 109 | >>> s.append(c1) 110 | >>> s.append(c2) 111 | >>> uri3 = 'cpe:/o:microsoft:windows_2000' 112 | >>> c3 = CPE2_2(uri3) 113 | >>> s.name_match(c3) 114 | True 115 | 116 | - TEST: matching with empty CPE name 117 | >>> uri1 = 'cpe:/o:microsoft:windows_2000::sp3:pro' 118 | >>> uri2 = 'cpe:/a:microsoft:ie:5.5' 119 | >>> c1 = CPE2_2(uri1) 120 | >>> c2 = CPE2_2(uri2) 121 | >>> s = CPESet2_2() 122 | >>> s.append(c1) 123 | >>> s.append(c2) 124 | >>> uri3 = 'cpe:/' 125 | >>> c3 = CPE2_2(uri3) 126 | >>> s.name_match(c3) 127 | True 128 | 129 | - TEST: not matching with CPE name 130 | >>> uri1 = 'cpe:/o:microsoft:windows_2000::sp3:pro' 131 | >>> uri2 = 'cpe:/a:microsoft:ie:5.5' 132 | >>> c1 = CPE2_2(uri1) 133 | >>> c2 = CPE2_2(uri2) 134 | >>> s = CPESet2_2() 135 | >>> s.append(c1) 136 | >>> s.append(c2) 137 | >>> uri3 = 'cpe:/o:redhat:enterprise_linux:4:ga' 138 | >>> c3 = CPE2_2(uri3) 139 | >>> s.name_match(c3) 140 | False 141 | 142 | - TEST: matching with ANY values explicit 143 | >>> uri1 = 'cpe:/o:microsoft:windows:vista' 144 | >>> uri2 = 'cpe:/o:cisco:ios:12.3:enterprise' 145 | >>> c1 = CPE2_2(uri1) 146 | >>> c2 = CPE2_2(uri2) 147 | >>> s = CPESet2_2() 148 | >>> s.append(c1) 149 | >>> s.append(c2) 150 | >>> uri3 = 'cpe:/o:microsoft::vista' 151 | >>> c3 = CPE2_2(uri3) 152 | >>> s.name_match(c3) 153 | True 154 | -------------------------------------------------------------------------------- /tests/unit/test_bugfixes.py: -------------------------------------------------------------------------------- 1 | from cpe import CPE 2 | from cpe.cpe2_3_uri import CPE2_3_URI 3 | 4 | 5 | def test_issue_8(): 6 | """TEST multiple %01 wildcards.""" 7 | current = CPE2_3_URI('cpe:/a:microsoft:internet_explorer:%01%018.%02:%02s%01%01%01').as_wfn() 8 | expected = 'wfn:[part="a", vendor="microsoft", product="internet_explorer", version="??8\\.*", update="*s???"]' 9 | assert current == expected 10 | 11 | 12 | def test_issue_11(): 13 | """TEST: correctly transform not applicable values for edition.""" 14 | current = CPE('wfn:[part="a", vendor="TauPan", product="cpelib", version="1\\.0\\.5", update=NA, edition=NA]').as_uri_2_3() 15 | expected = 'cpe:/a:taupan:cpelib:1.0.5:-:-' 16 | assert current == expected 17 | -------------------------------------------------------------------------------- /tests/unit/test_cpe1_1.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | import pytest 4 | 5 | from cpe.cpe import CPE 6 | from cpe.cpe1_1 import CPE1_1 7 | from cpe.comp.cpecomp import CPEComponent 8 | from cpe.comp.cpecomp1_1 import CPEComponent1_1 9 | 10 | 11 | # 12 | # Test for _get_attribute_values(self) 13 | # 14 | def test_get_attribute_values_1(): 15 | """(version 1.1) not negate components""" 16 | c = CPE('cpe:///microsoft:ie:6.0') 17 | att = CPEComponent.ATT_VENDOR 18 | assert c.get_attribute_values(att) == ['microsoft'] 19 | 20 | 21 | def test_get_attribute_values_2(): 22 | """CPE Name with multiple parts and elements""" 23 | c = CPE('cpe://sun:sunos:5.9/bea:weblogic:8.1;mysql:server:5.0') 24 | att = CPEComponent.ATT_VENDOR 25 | assert c.get_attribute_values(att) == ['sun', 'bea', 'mysql'] 26 | 27 | 28 | # 29 | # Test for __getitem__(self, i) 30 | # 31 | def test_getitem_1(): 32 | """good index""" 33 | c = CPE1_1('cpe:///sun_microsystem:sun@os:5.9:#update') 34 | assert isinstance(c[1], CPEComponent1_1) 35 | assert str(c[1]) == "sun@os" 36 | 37 | 38 | def test_getitem_2(): 39 | """bad index""" 40 | c = CPE1_1('cpe:///sun_microsystem:sun@os:5.9:#update') 41 | with pytest.raises(IndexError): 42 | c[6] 43 | 44 | 45 | def test_getitem_3(): 46 | """bad index""" 47 | c = CPE1_1('cpe://') 48 | with pytest.raises(IndexError): 49 | c[0] 50 | 51 | 52 | # 53 | # Test for __new__(cls, cpe_str, *args, **kwargs) 54 | # 55 | @pytest.mark.parametrize('s', [ 56 | # An empty hardware part, and no OS or application part. 57 | 'cpe:/', 58 | 59 | # An application part 60 | 'cpe://microsoft:windows:2000', 61 | 62 | # An OS part with an application part, 63 | 'cpe://redhat:enterprise_linux:3:as/apache:httpd:2.0.52', 64 | 65 | # An hardware part with OS part 66 | 'cpe:/cisco::3825/cisco:ios:12.3:enterprise', 67 | 68 | # An application part 69 | 'cpe:///microsoft:ie:6.0', 70 | 71 | # OS part with operator OR (two subcomponents) 72 | 'cpe://microsoft:windows:xp!vista', 73 | 74 | # OS part with operator NOT (a subcomponent) 75 | 'cpe://microsoft:windows:~xp', 76 | 77 | # OS part with two elements in application part 78 | 'cpe://sun:sunos:5.9/bea:weblogic:8.1;mysql:server:5.0', 79 | 80 | # CPE with special characters 81 | 'cpe:///sun_microsystem:sun@os:5.9:#update', 82 | ]) 83 | def test_new_legal_cpe(s): 84 | """legal cpe""" 85 | CPE1_1(s) # Must instantiate just fine 86 | 87 | 88 | @pytest.mark.parametrize('s', [ 89 | # Bad URI syntax 90 | 'baduri', 91 | # URI with whitespaces 92 | 'cpe:/con espacios', 93 | # Two operators in a subcomponent 94 | 'cpe://microsoft:windows:~2000!2007', 95 | ]) 96 | def test_new_ilegal_cpe(s): 97 | """ilegal cpe""" 98 | with pytest.raises(ValueError): 99 | CPE1_1(s) 100 | 101 | # 102 | # Test for __len__(self) 103 | # 104 | @pytest.mark.parametrize('s,l', [ 105 | # A CPE name with empty parts 106 | ("cpe:///", 0), 107 | 108 | # A CPE name with two parts (hw and os) and some elements empty and 109 | # with values 110 | ("cpe:/cisco::3825/cisco:ios:12.3:enterprise", 7), 111 | 112 | # A CPE name with a application part and a component with two 113 | # subcomponents 114 | ("cpe:///adobe:acrobat:6.0:std!pro", 4), 115 | ]) 116 | def test_len(s, l): 117 | assert len(CPE1_1(s)) == l 118 | 119 | 120 | # 121 | # Test for __str__(self) 122 | # 123 | def test_str_1(): 124 | """not negate components""" 125 | current = str(CPE1_1('cpe:///microsoft:ie:6.0')) 126 | expected = "CPE v1.1: cpe:///microsoft:ie:6.0" 127 | assert current == expected 128 | 129 | def test_str_2(): 130 | """negate components""" 131 | current = str(CPE1_1('cpe://microsoft:windows:~xp')) 132 | expected = "CPE v1.1: cpe://microsoft:windows:~xp" 133 | assert current == expected 134 | 135 | -------------------------------------------------------------------------------- /tests/unit/test_cpe2_2.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | import pytest 4 | 5 | from cpe.cpe import CPE 6 | from cpe.cpe2_2 import CPE2_2 7 | from cpe.comp.cpecomp import CPEComponent 8 | from cpe.comp.cpecomp2_2 import CPEComponent2_2 9 | 10 | 11 | # 12 | # Test for _get_attribute_values(self) 13 | # 14 | def test_get_attribute_values_1(): 15 | c = CPE2_2('cpe:/a:mozilla:firefox:2.0.0.6::osx:zh-tw') 16 | assert c.get_attribute_values(CPEComponent.ATT_VENDOR) == ['mozilla'] 17 | assert c.get_attribute_values(CPEComponent.ATT_LANGUAGE) == ['zh-tw'] 18 | 19 | 20 | # 21 | # Test for __getitem__(self, i) 22 | # 23 | def test_getitem_1(): 24 | """good index""" 25 | c = CPE2_2('cpe:/a:mozilla:firefox:2.0.0.6::osx:zh-tw') 26 | assert isinstance(c[1], CPEComponent2_2) 27 | assert str(c[1]) == "mozilla" 28 | 29 | 30 | def test_getitem_2(): 31 | """bad index""" 32 | c = CPE2_2('cpe:/a:mozilla:firefox:2.0.0.6::osx:zh-tw') 33 | with pytest.raises(IndexError): 34 | c[8] 35 | 36 | 37 | def test_getitem_3(): 38 | """bad index""" 39 | c = CPE2_2('cpe:/') 40 | with pytest.raises(IndexError): 41 | c[0] 42 | 43 | 44 | # 45 | # Test for __new__(cls, cpe_str, *args, **kwargs) 46 | # 47 | @pytest.mark.parametrize('s', [ 48 | # An empty hardware part, and no OS or application part. 49 | 'cpe:/', 50 | 51 | # An operation system. The CPE Name below designates all 52 | # Professional editions of Microsoft Windows XP, regardless of 53 | # service pack level. 54 | 'cpe:/o:microsoft:windows_xp:::pro', 55 | 56 | # An application 57 | 'cpe:/a:acme:product:1.0:update2:-:en-us', 58 | 59 | # An application 60 | 'cpe:/a:acme:product:1.0:update2::en-us', 61 | 62 | # An application 63 | 'cpe:/a:acme:product:1.0:update2:pro:en-us', 64 | 65 | # An application. The vendor Best Software may not have a qualified 66 | # DNS name, so a CPE Name for their application ABC123 would be as 67 | # follows: 68 | 'cpe:/a:best_software:abc123', 69 | 70 | # For applications that do not have a vendor or organization 71 | # associated with them, this component should use a developer's 72 | # name. Note that multi-word names should use underscores instead of 73 | # spaces. 74 | 'cpe:/a:jon_smith:tool_name:1.2.3', 75 | 76 | # An application. Multi-word product names and designations should 77 | # be spelled out in full, replacing spaces with underscores. The 78 | # example below shows how this would look for the Zone Labs 79 | # ZoneAlarm Internet Security Suite version 7.0. 80 | 'cpe:/a:zonelabs:zonealarm_internet_security_suite:7.0', 81 | 82 | # The following example denotes Adobe Reader version 8.1 83 | 'cpe:/a:adobe:reader:8.1', 84 | 85 | # The following example denotes Red Hat Enterprise Linux 4.0 Update 86 | # 4. 87 | 'cpe:/o:redhat:enterprise_linux:4:update4', 88 | 89 | # CPE Name of Red Hat operating system with initial release of 90 | # Enterprise Linux 4 91 | 'cpe:/o:redhat:enterprise_linux:4:ga', 92 | 93 | # An operating system 94 | 'cpe:/o:microsoft:windows_2000::sp4:pro', 95 | 96 | # An application 97 | 'cpe:/a:mozilla:firefox:2.0.0.6::osx:zh-tw', 98 | 99 | # This example name below represents a typical CPE Name that refers 100 | # to the Microsoft Windows 2000 operating system, all editions and 101 | # update levels. 102 | 'cpe:/o:microsoft:windows_2000', 103 | 104 | # This example CPE Name below identifies Microsoft?s Windows XP 105 | # operating system, Professional Edition, update level "Service Pack 106 | # 2". 107 | 'cpe:/o:microsoft:windows_xp::sp2:pro', 108 | 109 | # This example name below refers to Red Hat Enterprise Linux 3 110 | # Advanced Server. 111 | 'cpe:/o:redhat:enterprise_linux:3::as', 112 | 113 | # This example specifies an application, specifically the Apache 114 | # Foundation HTTP server version 2.0.52. 115 | 'cpe:/a:apache:httpd:2.0.52', 116 | 117 | # This example name below refers to a particular web browser, 118 | # regardless of any hardware or particular OS on which it is 119 | # running. 120 | 'cpe:/a:microsoft:ie:6.0', 121 | 122 | # This example name below refers to a Cisco model 3825 integrated 123 | # services router. 124 | 'cpe:/h:cisco:router:3825', 125 | 126 | # The example name below identifies a particular laptop computer 127 | # hardware platform. The vendor is Dell Computer, the product line 128 | # name is "Inspiron", and the version (or model in this example) 129 | # number is 8500. 130 | 'cpe:/h:dell:inspiron:8500', 131 | 132 | # The CPE Name below shows an example for a virtual hardware 133 | # platform. 134 | 'cpe:/h:emc:vmware_esx:2.5', 135 | 136 | # The CPE name below shows a valid CPE that contains a '/' in the product 137 | 'cpe:/a:intel:proset\/wireless_wifi' 138 | ]) 139 | def test_new_legal_cpe(s): 140 | """legal cpe""" 141 | CPE2_2(s) # Must instantiate just fine 142 | 143 | 144 | @pytest.mark.parametrize('s', [ 145 | # bad URI syntax 146 | 'baduri', 147 | 148 | # URI with whitespaces 149 | 'cpe:/con espacios', 150 | ]) 151 | def test_new_ilegal_cpe(s): 152 | """ilegal cpe""" 153 | with pytest.raises(ValueError): 154 | CPE2_2(s) 155 | 156 | 157 | # 158 | # Test for __len__(self) 159 | # 160 | @pytest.mark.parametrize('s,l', [ 161 | # A CPE name without components 162 | ("cpe:/", 0), 163 | 164 | # A CPE name with some full components 165 | ("cpe:/a:i4s:javas", 3), 166 | 167 | # A CPE name with some empty components 168 | ("cpe:/a:i4s:::javas", 5), 169 | 170 | # A CPE name with all components 171 | ("cpe:/a:acme:product:1.0:update2:-:en-us", 7), 172 | ]) 173 | def test_len(s, l): 174 | assert len(CPE2_2(s)) == l 175 | 176 | 177 | # 178 | # Test for __str__(self) 179 | # 180 | def test_str(): 181 | """not negate components""" 182 | current = str(CPE2_2('cpe:/a:acme:product:1.0:update2:-:en-us')) 183 | expected = "CPE v2.2: cpe:/a:acme:product:1.0:update2:-:en-us" 184 | assert current == expected 185 | -------------------------------------------------------------------------------- /tests/unit/test_cpe2_3_uri_sparse.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from cpe.cpe2_3_uri import CPE2_3_URI 3 | 4 | import pytest 5 | 6 | 7 | def test_regular_cpe(): 8 | uri = 'cpe:/a:TauPan:cpe:1.2.1BETA1' 9 | c = CPE2_3_URI(uri) 10 | assert c.as_wfn() == 'wfn:[part="a", vendor="taupan", product="cpe", version="1\\.2\\.1beta1"]' 11 | assert c.as_uri_2_3() == uri.lower() 12 | 13 | 14 | def test_percent_encoded(): 15 | uri = 'cpe:/a:TauPan:cpe%7cextra:1.2.1BETA1' 16 | c = CPE2_3_URI(uri) 17 | assert c.as_wfn() == 'wfn:[part="a", vendor="taupan", product="cpe\\|extra", version="1\\.2\\.1beta1"]' 18 | assert c.as_uri_2_3() == uri.lower() 19 | 20 | 21 | def test_just_part(): 22 | uri = 'cpe:/a' 23 | c = CPE2_3_URI(uri) 24 | assert c.as_wfn() == 'wfn:[part="a"]' 25 | assert c.as_uri_2_3() == uri.lower() 26 | 27 | 28 | def test_just_vendor(): 29 | uri = 'cpe:/:taupan' 30 | c = CPE2_3_URI(uri) 31 | assert c.as_wfn() == 'wfn:[part=ANY, vendor="taupan"]' 32 | assert c.as_uri_2_3() == uri.lower() 33 | 34 | 35 | def test_just_product(): 36 | uri = 'cpe:/::cpe' 37 | c = CPE2_3_URI(uri) 38 | assert c.as_wfn() == 'wfn:[part=ANY, vendor=ANY, product="cpe"]' 39 | assert c.as_uri_2_3() == uri.lower() 40 | 41 | 42 | def test_just_version(): 43 | uri = 'cpe:/:::version' 44 | cpe = CPE2_3_URI(uri) 45 | assert cpe.as_wfn() == ('wfn:[part=ANY, vendor=ANY, product=ANY, ' 46 | 'version="version"' 47 | ']') 48 | assert cpe.as_uri_2_3() == uri.lower() 49 | 50 | 51 | def test_just_update(): 52 | uri = 'cpe:/::::update' 53 | cpe = CPE2_3_URI(uri) 54 | assert cpe.as_wfn() == ('wfn:[part=ANY, vendor=ANY, product=ANY, ' 55 | 'version=ANY, ' 56 | 'update="update"' 57 | ']') 58 | assert cpe.as_uri_2_3() == uri.lower() 59 | 60 | 61 | def test_just_legacy_edition_uri(): 62 | uri = 'cpe:/:::::legacy_edition' 63 | cpe = CPE2_3_URI(uri) 64 | assert cpe.as_uri_2_3() == uri.lower() 65 | 66 | 67 | @pytest.mark.xfail 68 | def test_just_legacy_edition_wfn(): 69 | uri = 'cpe:/:::::legacy_edition' 70 | cpe = CPE2_3_URI(uri) 71 | # not sure if this is correct, see 72 | # https://github.com/nilp0inter/cpe/issues/28#issuecomment-253195951 73 | assert cpe.as_wfn() == ('wfn:[part=ANY, vendor=ANY, product=ANY, ' 74 | 'version=ANY, ' 75 | 'update=ANY, ' 76 | 'edition="legacy_edition"' 77 | ']') 78 | 79 | 80 | def test_full_packed_edition(): 81 | uri = 'cpe:/:::::~edition~sw_edition~target_sw~target_hw~other' 82 | cpe = CPE2_3_URI(uri) 83 | assert cpe.as_wfn() == ('wfn:[part=ANY, vendor=ANY, product=ANY, ' 84 | 'version=ANY, ' 85 | 'update=ANY, ' 86 | 'edition="edition", ' 87 | 'sw_edition="sw_edition", ' 88 | 'target_sw="target_sw", ' 89 | 'target_hw="target_hw", ' 90 | 'other="other"' 91 | ']') 92 | assert cpe.as_uri_2_3() == uri.lower() 93 | 94 | 95 | def test_legacy_edition_uri(): 96 | uri = 'cpe:/a:TauPan:cpe:1.2.1BETA1::legacy_edition' 97 | c = CPE2_3_URI(uri) 98 | assert c.as_uri_2_3() == uri.lower() 99 | 100 | 101 | @pytest.mark.xfail # see above 102 | def test_legacy_edition_wfn(): 103 | uri = 'cpe:/a:TauPan:cpe:1.2.1BETA1::legacy_edition' 104 | c = CPE2_3_URI(uri) 105 | assert c.as_wfn() == 'wfn:[part="a", vendor="taupan", product="cpe", version="1\\.2\\.1beta1", update=ANY, edition="legacy_edition"]' 106 | 107 | 108 | def test_legacy_edition_packed(): 109 | uri = 'cpe:/a:TauPan:cpe:1.2.1BETA1::~legacy_edition~~~~' 110 | c = CPE2_3_URI(uri) 111 | assert c.as_wfn() == 'wfn:[part="a", vendor="taupan", product="cpe", version="1\\.2\\.1beta1", update=ANY, edition="legacy_edition", sw_edition=ANY, target_sw=ANY, target_hw=ANY, other=ANY]' 112 | assert c.as_uri_2_3() == 'cpe:/a:taupan:cpe:1.2.1beta1::legacy_edition' 113 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | # content of: tox.ini , put in same dir as setup.py 2 | [tox] 3 | envlist = py27,py34,py35,py36,py37,pypy 4 | 5 | [testenv] 6 | deps = -r requirements-dev.txt 7 | commands = 8 | py.test -vv tests/unit 9 | -------------------------------------------------------------------------------- /utils/provision.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # If deps are installed exit gracefully. 4 | which python2.6 && \ 5 | which python2.7 && \ 6 | which python3.2 && \ 7 | which python3.3 && \ 8 | which python3.4 && \ 9 | which jython && \ 10 | which pypy && \ 11 | exit 0 12 | 13 | # Add deadsnakes ppa https://launchpad.net/~fkrull/+archive/deadsnakes . 14 | apt-get update 15 | apt-get install -y python-software-properties 16 | add-apt-repository -y ppa:fkrull/deadsnakes 17 | apt-get update 18 | 19 | # Install all supported python version. 20 | apt-get install -y python2.6 python2.7 python3.1 python3.2 python3.3 python3.4 jython pypy 21 | 22 | # Install the development dependencies. 23 | apt-get install -y python-pip 24 | pip install -r /vagrant/requirements/develop.txt 25 | --------------------------------------------------------------------------------