Blob Blame History Raw
%global srcname oletools

%global _provides \
Provides: bundled(DridexUrlDecoder) \
Provides: bundled(tablestream) = 0.07 \
Provides: bundled(xglob) = 0.06 \
Provides: bundled(xxxswf) = 0.1 \
Provides: bundled(zipfile27) = 0.01

%global _description \
The python-oletools is a package of python tools from Philippe Lagadec \
to analyze Microsoft OLE2 files (also called Structured Storage, \
Compound File Binary Format or Compound Document File Format), \
such as Microsoft Office documents or Outlook messages, mainly for \
malware analysis, forensics and debugging. \
It is based on the olefile parser. \
See http://www.decalage.info/python/oletools for more info.


Name:           python-%{srcname}
Version:        0.51
Release:        4%{?dist}
Summary:        Tools to analyze Microsoft OLE2 files

# oletools/*.py: BSD
# oletools/olevba*.py: BSD and MIT
# oletools/thirdparty/xxxswf/*.py: No license specified
# oletools/thirdparty/DridexUrlDecoder/*.py: No license specified
# oletools/thirdparty/xglob/*.py: BSD
# oletools/thirdparty/tablestream/*.py: BSD
# oletools/thirdparty/zipfile27/*.py: Python
License:        BSD and MIT and Python
URL:            https://www.decalage.info/python/oletools
Source0:        https://github.com/decalage2/%{srcname}/archive/v%{version}/%{srcname}-%{version}.tar.gz
Patch0:         %{name}-thirdparty.patch

BuildArch:      noarch
BuildRequires:  python2-devel
BuildRequires:  python%{python3_pkgversion}-devel

# No python3-pymilter, python2-pymilter only at F28+, python-pymilter at EPEL 7
%if 0%{?fedora} >= 28
BuildRequires:  python2-pymilter
%else
BuildRequires:  python-pymilter
%endif

# python2-pyparsing and python3-pyparsing at Fedora, pyparsing at RHEL 7
%if 0%{?fedora}
BuildRequires:  python2-pyparsing
BuildRequires:  python%{python3_pkgversion}-pyparsing
%else
BuildRequires:  pyparsing
%endif

BuildRequires:  python2-colorclass
BuildRequires:  python%{python3_pkgversion}-colorclass

# python2-easygui only at F28+ and EPEL 7
%if 0%{?fedora} >= 28 || 0%{?rhel} >= 7
BuildRequires:  python2-easygui
%else
BuildRequires:  python-easygui
%endif
BuildRequires:  python%{python3_pkgversion}-easygui

BuildRequires:  python2-olefile
BuildRequires:  python%{python3_pkgversion}-olefile

# python2-prettytable and python3-prettytable at Fedora, python-prettytable at EPEL 7
%if 0%{?fedora} >= 28
BuildRequires:  python2-prettytable
%else
BuildRequires:  python-prettytable
%endif
%if 0%{?fedora}
BuildRequires:  python%{python3_pkgversion}-prettytable
%endif

%description %{_description}


%package -n python2-%{srcname}
Summary:        %{summary}
%{?python_provide:%python_provide python2-%{srcname}}
%{_provides}

# python2-pymilter only at F28+, python-pymilter at EPEL 7
%if 0%{?fedora} >= 28
Requires:       python2-pymilter
%else
Requires:       python-pymilter
%endif

# python2-pyparsing at Fedora, pyparsing at RHEL 7
%if 0%{?fedora}
Requires:       python2-pyparsing
%else
Requires:       pyparsing
%endif

Requires:       python2-colorclass

# python2-easygui only at F28+ and EPEL 7
%if 0%{?fedora} >= 28 || 0%{?rhel} >= 7
Requires:       python2-easygui
%else
Requires:       python-easygui
%endif

Requires:       python2-olefile

# python2-prettytable only at Fedora 28+, python-prettytable at EPEL 7
%if 0%{?fedora} >= 28
Requires:       python2-prettytable
%else
Requires:       python-prettytable
%endif

%description -n python2-%{srcname} %{_description}

Python2 version.


%if 0%{?fedora}
%package -n python%{python3_pkgversion}-%{srcname}
Summary:        %{summary}
%{?python_provide:%python_provide python%{python3_pkgversion}-%{srcname}}
%{_provides}

# No python3-pymilter
Requires:       python%{python3_pkgversion}-pyparsing
Requires:       python%{python3_pkgversion}-colorclass
Requires:       python%{python3_pkgversion}-easygui
Requires:       python%{python3_pkgversion}-olefile
Requires:       python%{python3_pkgversion}-prettytable

%description -n python%{python3_pkgversion}-%{srcname} %{_description}

Python3 version. Executables are experimental and might not be fully usable.
%endif


%package -n python-%{srcname}-doc
Summary:        Documentation files for %{name}
%{?python_provide:%python_provide python2-%{srcname}-doc}
%if 0%{?fedora}
%{?python_provide:%python_provide python%{python3_pkgversion}-%{srcname}-doc}
%endif

%description -n python-%{srcname}-doc %{_description}


%prep
%autosetup -n %{srcname}-%{version}

# Use globally installed python modules instead
for i in colorclass easygui olefile prettytable pyparsing; do
  rm -rf "oletools/thirdparty/${i}"
done

sed -i -e '
  s|from oletools.thirdparty import olefile|import olefile|;
  s|from oletools.thirdparty.olefile import olefile|from olefile import olefile|;
  s|from oletools.thirdparty.prettytable import prettytable|import prettytable|;
  s|from oletools.thirdparty.pyparsing.pyparsing import|from pyparsing import|;
  s|from thirdparty.pyparsing.pyparsing import|from pyparsing import|;
  s|from .thirdparty import olefile|import olefile|;
  s|from oletools.thirdparty.easygui import easygui|import easygui|;
' */*.py


%build
%if 0%{?fedora}
%py3_build
%endif
%py2_build


%install
%if 0%{?fedora}
%py3_install

pushd %{buildroot}%{_bindir}
  main=$(%{__python3} -c "import sys; sys.stdout.write('{0.major}'.format(sys.version_info))")  # e.g. 3
  full=$(%{__python3} -c "import sys; sys.stdout.write('{0.major}.{0.minor}'.format(sys.version_info))")  # e.g. 3.4

  for i in ezhexviewer mraptor olebrowse oledir oleid olemap olemeta oleobj oletimes olevba pyxswf rtfobj; do
    mv -f "${i}" "${i}-${full}"
    ln -s "${i}-${full}" "${i}-${main}"
  done
popd

# Remove '\r' line ending and shebang from non-executable python libraries
for file in %{buildroot}%{python3_sitelib}/%{srcname}/{.,*/*}/*.py; do
  sed -e '1{\@^#![[:space:]]*/usr/bin/env python@d}' -e 's|\r$||' "${file}" > "${file}.new"
  touch -c -r "${file}" "${file}.new"
  mv -f "${file}.new" "${file}"
done
%endif

%py2_install
pushd %{buildroot}%{_bindir}
  main=$(%{__python2} -c "import sys; sys.stdout.write('{0.major}'.format(sys.version_info))")  # e.g. 2
  full=$(%{__python2} -c "import sys; sys.stdout.write('{0.major}.{0.minor}'.format(sys.version_info))")  # e.g. 2.7

  for i in ezhexviewer mraptor olebrowse oledir oleid olemap olemeta oleobj oletimes olevba pyxswf rtfobj; do
    mv -f "${i}" "${i}-${full}"
    ln -s "${i}-${full}" "${i}-${main}"

    # For now the 2.7 is the default version, python3 support is experimental
    ln -s "${i}-${full}" "${i}"
  done
popd

# Remove '\r' line ending and shebang from non-executable python libraries
for file in %{buildroot}%{python2_sitelib}/%{srcname}/{.,*/*}/*.py; do
  sed -e '1{\@^#![[:space:]]*/usr/bin/env python@d}' -e 's|\r$||' "${file}" > "${file}.new"
  touch -c -r "${file}" "${file}.new"
  mv -f "${file}.new" "${file}"
done

# Remove files that should either go to %%doc or to %%license
rm -rf %{buildroot}{%{python2_sitelib},%{python3_sitelib}}/%{srcname}/{doc,LICENSE.txt,README.*}
rm -f %{buildroot}{%{python2_sitelib},%{python3_sitelib}}/%{srcname}/thirdparty/DridexUrlDecoder/LICENSE.txt
rm -f %{buildroot}{%{python2_sitelib},%{python3_sitelib}}/%{srcname}/thirdparty/xglob/LICENSE.txt
rm -f %{buildroot}{%{python2_sitelib},%{python3_sitelib}}/%{srcname}/thirdparty/xxxswf/LICENSE.txt
rm -f %{buildroot}{%{python2_sitelib},%{python3_sitelib}}/%{srcname}/thirdparty/zipfile27/LICENSE.txt

# Prepare licenses from bundled code for later %%license usage
mv -f %{srcname}/thirdparty/DridexUrlDecoder/LICENSE.txt DridexUrlDecoder-LICENSE.txt
mv -f %{srcname}/thirdparty/xglob/LICENSE.txt xglob-LICENSE.txt
mv -f %{srcname}/thirdparty/xxxswf/LICENSE.txt xxxswf-LICENSE.txt
mv -f %{srcname}/thirdparty/zipfile27/LICENSE.txt zipfile27-LICENSE.txt

# Old pyparsing in RHEL 7 -> replace pyparsing.infixNotation by pyparsing.operatorPrecedence
%if 0%{?rhel} && 0%{?rhel} < 8
sed -e 's|infixNotation|operatorPrecedence|g' -i %{buildroot}%{python2_sitelib}/%{srcname}/olevba.py
%endif


%check
%{__python2} setup.py test

%if 0%{?fedora}
# Python3 test fails for:
# Milter on mraptor_milter.py -> missing python3 version, the mraptor_milter.py will work only with python2
# ioString on olevba.pu -> there is olevba3.py version
%{__python3} setup.py test || true
%endif


# Note that there is no %%files section for the unversioned python module if we are building for several python runtimes
%files -n python2-%{srcname}
%license %{srcname}/LICENSE.txt *-LICENSE.txt 
%doc README.md
%{python2_sitelib}/*
%{_bindir}/ezhexviewer-2*
%{_bindir}/olebrowse-2*
%{_bindir}/oledir-2*
%{_bindir}/oleid-2*
%{_bindir}/olemap-2*
%{_bindir}/olemeta-2*
%{_bindir}/oleobj-2*
%{_bindir}/oletimes-2*
%{_bindir}/olevba-2*
%{_bindir}/mraptor-2*
%{_bindir}/pyxswf-2*
%{_bindir}/rtfobj-2*
%{_bindir}/ezhexviewer
%{_bindir}/olebrowse
%{_bindir}/oledir
%{_bindir}/oleid
%{_bindir}/olemap
%{_bindir}/olemeta
%{_bindir}/oleobj
%{_bindir}/oletimes
%{_bindir}/olevba
%{_bindir}/mraptor
%{_bindir}/pyxswf
%{_bindir}/rtfobj


%if 0%{?fedora}
%files -n python%{python3_pkgversion}-%{srcname}
%license %{srcname}/LICENSE.txt *-LICENSE.txt 
%doc README.md
%{python3_sitelib}/*
%{_bindir}/ezhexviewer-3*
%{_bindir}/olebrowse-3*
%{_bindir}/oledir-3*
%{_bindir}/oleid-3*
%{_bindir}/olemap-3*
%{_bindir}/olemeta-3*
%{_bindir}/oleobj-3*
%{_bindir}/oletimes-3*
# ModuleNotFoundError: No module named 'cStringIO'
%exclude %{_bindir}/olevba-3*
# ModuleNotFoundError: No module named 'cStringIO'
%exclude %{_bindir}/mraptor-3*
%{_bindir}/pyxswf-3*
%{_bindir}/rtfobj-3*
%endif


%files -n python-%{srcname}-doc
%doc %{srcname}/doc/*
%doc cheatsheet


%changelog
* Fri Feb 09 2018 Fedora Release Engineering <releng@fedoraproject.org> - 0.51-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild

* Mon Oct 23 2017 Robert Scheck <robert@fedoraproject.org> 0.51-3
- Correct line endings and remove shebang from non-executable
  python libraries (#1505374 #c5)
- Clarify python3 related scripts in %%description (#1505374 #c4)
- Correct summary of -doc subpackage (#1505374 #c2)

* Thu Oct 05 2017 Robert Scheck <robert@fedoraproject.org> 0.51-2
- Various spec file enhancements (#1471561)
- Added spec file conditionals to build for EPEL 7

* Thu Jun 22 2017 Michal Ambroz <rebus at, seznam.cz> 0.51-1
- bump to 0.51 release

* Thu Jun 22 2017 Michal Ambroz <rebus at, seznam.cz> 0.51-0.3.dev11.b4b52d22
- gaps in python3 detected, using python2 as default

* Thu Jun 15 2017 Michal Ambroz <rebus at, seznam.cz> 0.51-0.2.dev11.b4b52d22
- initial version