BloodHound.py icon indicating copy to clipboard operation
BloodHound.py copied to clipboard

cohabitation of bloodhound-ce-python with bloodhound-python

Open noraj opened this issue 10 months ago • 2 comments
trafficstars

As bloodhound-ce-python and bloodhound-python targets different softwares (BH v5 and BH v4), it is useful to have both installed at the same time.

However, from the package structure, files deployed conflicts prevent to get both installed simultaneously. Changing the 2 following lines by adding the -ce suffix in setup.py is not enough.

https://github.com/dirkjanm/BloodHound.py/blob/3def775fd2df9a4eefe916f42f41440d51e89279/setup.py#L3 https://github.com/dirkjanm/BloodHound.py/blob/3def775fd2df9a4eefe916f42f41440d51e89279/setup.py#L28

The conflict happens under usr/lib/python3.13/site-packages/bloodhound/*, the CE version should propably be deployed under usr/lib/python3.13/sote-packages/bloodhound-ce/* instead.

image

All those files are conflicting:

➜ comm -1 -2 <(tar tvf packages/bloodhound-python/bloodhound-python-v1.0.1.r163.g44bd5c2-1-any.pkg.tar.zst | awk '{print $6}' | sort ) <(tar tvf packages/bloodhound-python-ce/bloodhound-python-ce-v1.0.1.r182.g3def775-1-any.pkg.tar.zst | awk '{print $6}' | sort )
[…]
usr/lib/python3.13/site-packages/bloodhound/
usr/lib/python3.13/site-packages/bloodhound/ad/
usr/lib/python3.13/site-packages/bloodhound/ad/authentication.py
usr/lib/python3.13/site-packages/bloodhound/ad/computer.py
usr/lib/python3.13/site-packages/bloodhound/ad/domain.py
usr/lib/python3.13/site-packages/bloodhound/ad/dumpntlm.py
usr/lib/python3.13/site-packages/bloodhound/ad/__init__.py
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/authentication.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/authentication.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/computer.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/computer.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/domain.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/domain.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/dumpntlm.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/dumpntlm.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/__init__.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/__init__.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/structures.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/structures.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/trusts.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/trusts.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/utils.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/__pycache__/utils.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/ad/structures.py
usr/lib/python3.13/site-packages/bloodhound/ad/trusts.py
usr/lib/python3.13/site-packages/bloodhound/ad/utils.py
usr/lib/python3.13/site-packages/bloodhound/enumeration/
usr/lib/python3.13/site-packages/bloodhound/enumeration/acls.py
usr/lib/python3.13/site-packages/bloodhound/enumeration/computers.py
usr/lib/python3.13/site-packages/bloodhound/enumeration/domains.py
usr/lib/python3.13/site-packages/bloodhound/enumeration/__init__.py
usr/lib/python3.13/site-packages/bloodhound/enumeration/memberships.py
usr/lib/python3.13/site-packages/bloodhound/enumeration/objectresolver.py
usr/lib/python3.13/site-packages/bloodhound/enumeration/outputworker.py
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/acls.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/acls.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/computers.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/computers.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/domains.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/domains.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/__init__.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/__init__.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/memberships.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/memberships.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/objectresolver.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/objectresolver.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/outputworker.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/enumeration/__pycache__/outputworker.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/__init__.py
usr/lib/python3.13/site-packages/bloodhound/lib/
usr/lib/python3.13/site-packages/bloodhound/lib/cstruct.py
usr/lib/python3.13/site-packages/bloodhound/lib/__init__.py
usr/lib/python3.13/site-packages/bloodhound/lib/__pycache__/
usr/lib/python3.13/site-packages/bloodhound/lib/__pycache__/cstruct.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/lib/__pycache__/cstruct.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/lib/__pycache__/__init__.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/lib/__pycache__/__init__.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/__main__.py
usr/lib/python3.13/site-packages/bloodhound/__pycache__/
usr/lib/python3.13/site-packages/bloodhound/__pycache__/__init__.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/__pycache__/__init__.cpython-313.pyc
usr/lib/python3.13/site-packages/bloodhound/__pycache__/__main__.cpython-313.opt-1.pyc
usr/lib/python3.13/site-packages/bloodhound/__pycache__/__main__.cpython-313.pyc
[…]

noraj avatar Jan 06 '25 21:01 noraj

As a workaround patch, I used what is probably the easiest way: rename the source folder to and all imports to bloodhound_ce.

Here's my package patch:

prepare() {
  cd "$_pkgname"

  # prevent conflicts with bloodhound-python package
  mv bloodhound/ bloodhound_ce/
  sed -i -E "s/'(bloodhound)(|\..+)'/'\1_ce\2'/g" setup.py # for the 4 packages=[] lines
  sed -i "s/=bloodhound:/=bloodhound_ce:/g" setup.py  # for the console_scripts line
  # rename all import
  find bloodhound_ce/ -type f -name '*.py' -exec sed -i 's/import bloodhound/import bloodhound_ce/g' {} \+ \
                                           -exec sed -i 's/from bloodhound/from bloodhound_ce/g' {} \+
}

I found no way to just rename the folder and play with package_dir that doesn't imply to change the imports AND that change the name deployed under site-package.

noraj avatar Jan 06 '25 23:01 noraj

hey Noraj, thanks for creating an issue on this. I am aware of the (big) drawback that the current structure has. The reason for keeping the same namespace is mostly for maintenance reasons. I maintain the legacy version and the CE version as separate branches, and merge bugfixes from the master branch into the CE branch. Moving the CE source into its own namespace means renaming the directories and imports like your script does. I'm afraid this would either break or hugely complicate the maintenance of the two versions simultaneously.

As a result there are currently a few options that do not break if you want to have both tools:

  • Have both in a separate manually managed virtual environment
  • Use a package manager like pipx which automatically isolates different tools in their own venvs

And you just added a third way, which is changing the naming convention at build time. I'll have to think about whether this is something that I'll also add in my own build process for pypi since it would make things easier to install for users. Permanently changing the package name in the source repository is not an option for the moment, maybe that would change when support for the legacy version is fully dropped.

dirkjanm avatar Jan 07 '25 09:01 dirkjanm