diff --git a/macosx/BUNDLING.md b/macosx/BUNDLING.md index 904144ee6..36c77f244 100644 --- a/macosx/BUNDLING.md +++ b/macosx/BUNDLING.md @@ -10,7 +10,7 @@ ## Jhbuild -In order to set up Jhbuild properly before building Nmap suite, follow the tutorial at [https://wiki.gnome.org/Projects/GTK%2B/OSX/Building](https://wiki.gnome.org/Projects/GTK%2B/OSX/Building), but keep reading this file if you encounter any error... +In order to set up Jhbuild properly before building Nmap suite, follow the tutorial at https://gitlab.gnome.org/GNOME/gtk-osx/-/wikis/home , but keep reading this file if you encounter any error... If you had any error, just type the following command to delete jhbuild, @@ -18,10 +18,10 @@ If you had any error, just type the following command to delete jhbuild, And we'll start over together: -1. First, simply download the following script in your _$HOME_ directory ([https://git.gnome.org/browse/gtk-osx/plain/gtk-osx-build-setup.sh](https://git.gnome.org/browse/gtk-osx/plain/gtk-osx-build-setup.sh)). Edit it to make sure that `MACOSX_DEPLOYMENT_TARGET` exists and is set to the lowest supported version of OS X, e.g. "10.11". Then run it: +1. First, simply download the following script in your _$HOME_ directory https://gitlab.gnome.org/GNOME/gtk-osx/raw/master/gtk-osx-setup.sh ~~~~ - $ sh gtk-osx-build-setup.sh + $ sh gtk-osx-setup.sh ~~~~ And add it to your _$PATH_, so you can run jhbuild without the absolute path: @@ -30,13 +30,13 @@ And we'll start over together: $ export PATH=$HOME/.local/bin:$PATH ~~~~ -2. In `~/.jhbuildrc-custom`, make sure that this line is setup properly and matches `MACOSX_DEPLOYMENT_TARGET` from step 1: +2. In `~/.config/jhbuildrc-custom`, make sure that this line is setup properly: ~~~~ - setup_sdk(target="10.11") + setup_sdk(target="10.14") ~~~~ -3. Now do, +3. Now do: ~~~~ $ jhbuild bootstrap-gtk-osx @@ -48,45 +48,9 @@ And we'll start over together: ~~~~ $ jhbuild build meta-gtk-osx-bootstrap - $ jhbuild build meta-gtk-osx-core + $ jhbuild build meta-gtk-osx-gtk3 + $ jhbuild build meta-gtk-osx-python3-gtk3 -5. Now we need Python2 and the GTK2 bindings for it, but gtk-osx has built -Python3, and the bindings will prefer that even though the dev headers aren't -present. Specifically, we need pycairo prior to 1.19 (when they dropped Python2 -support) and gtk-integration-python. There's got to be a better way, but what I -did was first install python2: - - $ jhbuild build python - -Then install pycairo. This is necessary because if it's missing for Python 2, -the other bindings won't build for Python 2 either. Make sure version is less -than 1.19 in ~/.cache/jhbuild/gtk-osx-python.modules. This may "succeed" but it -will have built the Python3 bindings. Clear out the build tree and make sure -the source will prefer python2: - - $ jhbuild build pycairo - $ rm -rf ~/.cache/jhbuild/build/pycairo-* - $ sed -i 's/python3/python2/' ~/gtk/source/pycairo-*/meson_options.txt - $ jhbuild build pycairo - -Now build the rest of the python bindings. Some of these will fail (and maybe -they failed as prereqs for pycairo earlier), so hang on and I'll tell you how -to fix those: - - $ jhbuild build meta-gtk-osx-python - -Ok, when you get a failure, that's your chance to reconfigure with python2. -Jhbuild will give you some options; choose "4. start a shell" and then check -for the proper configuration command (may be visible in scrollback, otherwise -check config.log) and copy it. Clear out the build directory (probably the -current directory, ~/.cache/jhbuild/build/package-name-version/*) then from -there run the configuration command with PYTHON variable overridden, e.g.: - - $ PYTHON=$(which python2) ~/gtk/source/package-name-version/configure --some-options - -Now exit that shell and go to the build step. This might mean "ignore error and -continue with build" or it might mean "rerun step build" depending on when the -error happened. ### Possible error @@ -110,14 +74,14 @@ $ export PATH=/opt/subversion/bin:$PATH Now that Jhbuild is properly configured, we need to install **gtk-mac-bundler** in order to render the bundle file: ~~~~ -$ git clone git://git.gnome.org/gtk-mac-bundler +$ git clone https://gitlab.gnome.org/GNOME/gtk-mac-bundler.git $ cd gtk-mac-bundler $ make install ~~~~ ## How to use #### Prerequisite: -—`openssl.modules`: +`openssl.modules`: This is a jhbuild moduleset that can be used to build/update openssl. @@ -126,5 +90,5 @@ This is a jhbuild moduleset that can be used to build/update openssl. Now use it like this: ~~~~ -$ jhbuild -m openssl.modules build nmap-deps +$ jhbuild -m file://$(pwd)/openssl.modules build openssl ~~~~ diff --git a/macosx/Info.plist.in b/macosx/Info.plist.in new file mode 100644 index 000000000..828d1fead --- /dev/null +++ b/macosx/Info.plist.in @@ -0,0 +1,33 @@ + + + + + CFBundleIdentifier + ${BUNDLE_IDENTIFIER} + CFBundleName + ${BUNDLE_NAME} + NSHumanReadableCopyright + ${APP_COPYRIGHT} + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${BUNDLE_EXE} + CFBundleGetInfoString + ${VERSION}, ${APP_COPYRIGHT} ${APP_WEB_SITE} + CFBundleIconFile + zenmap.icns + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleShortVersionString + ${VERSION} + CFBundleSignature + ???? + CFBundleVersion + ${VERSION} + LSMinimumSystemVersion + ${OSX_MIN_VERSION} +${EXTRA_DICT_CONTENT} + + diff --git a/macosx/Makefile b/macosx/Makefile index db8277f3d..6a529171b 100644 --- a/macosx/Makefile +++ b/macosx/Makefile @@ -3,7 +3,7 @@ export NMAP_VERSION := $(shell echo NMAP_VERSION | $(CPP) -imacros ../nmap.h - | sed -n '$$s/[" ]//g;$$p') OSX_VERSION=$(shell sw_vers -productVersion | cut -d'.' -f1,2 | tr -d ' ') -OSX_MIN_VERSION = 10.15 +export OSX_MIN_VERSION = 10.15 NAME_VERSION = nmap-$(NMAP_VERSION)$(if $(APPENDAGE),-$(APPENDAGE)) @@ -13,23 +13,22 @@ PKG_NAME = $(NAME_VERSION).mpkg IMAGE_STAGING_DIR = $(NAME_VERSION) NMAP_BUILD_DIR = nmap-build -NMAP_STAGING_DIR = nmap-root +NMAP_STAGING_DIR = nmap.app ZENMAP_BUILD_DIR = zenmap-build -ZENMAP_STAGING_DIR = zenmap-root +ZENMAP_STAGING_DIR = $(ZENMAP_BUILD_DIR)/zenmap/dist/Zenmap.app NCAT_BUILD_DIR = ncat-build -NCAT_STAGING_DIR = ncat-root +NCAT_STAGING_DIR = ncat.app NDIFF_BUILD_DIR = ndiff-build -NDIFF_STAGING_DIR = ndiff-root +NDIFF_STAGING_DIR = ndiff.app NPING_BUILD_DIR = nping-build -NPING_STAGING_DIR = nping-root +NPING_STAGING_DIR = nping.app JHBUILD_PREFIX=$(HOME)/gtk/inst JHBUILD_SOURCE=$(HOME)/gtk/source -PREFIX = /usr/local # Extra distribution file names README_FILE = README.md @@ -39,16 +38,9 @@ LICENSES_FILE = licenses EXTRA_DIST = README.md ../LICENSE ../docs/3rd-party-licenses.txt ../docs/licenses -CONFIGURE_ARGS = --prefix="$(PREFIX)" --with-libdnet=included --with-libpcap=included --with-libpcre=included --with-liblua=included CC="$(CC)" CXX="$(CXX)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" PYTHON="$(PYTHON)" - CFLAGS = -mmacosx-version-min=$(OSX_MIN_VERSION) CXXFLAGS = -mmacosx-version-min=$(OSX_MIN_VERSION) -# Jhbuild static libraries -PYTHON = $(JHBUILD_PREFIX)/bin/python3 -OPENSSL_STATIC = $(JHBUILD_PREFIX)/lib/libssl.a $(JHBUILD_PREFIX)/lib/libcrypto.a -LIBZ_STATIC = $(JHBUILD_PREFIX)/lib/libz.a - # These are the positions used by the createdmg.sh and check_test.sh scripts export ICON_SIZE=88 export FONT_SIZE=13 @@ -83,10 +75,10 @@ $(IMAGE_STAGING_DIR)/$(PKG_NAME): check-nmap check-ncat check-ndiff check-zenmap mkdir -p $(IMAGE_STAGING_DIR) cp -rf $(EXTRA_DIST) $(IMAGE_STAGING_DIR)/ # Create packages (.pkg) for all the components to install in the installer (.mpkg) - pkgbuild --root $(NMAP_STAGING_DIR) --identifier org.insecure.nmap --version $(NMAP_VERSION) --install-location /usr/local nmap.pkg - pkgbuild --root $(NCAT_STAGING_DIR) --identifier org.insecure.nmap.ncat --version $(NMAP_VERSION) --install-location /usr/local ncat.pkg - pkgbuild --root $(NDIFF_STAGING_DIR)/usr/local --identifier org.insecure.nmap.ndiff --version $(NMAP_VERSION) --install-location /usr/local ndiff.pkg - pkgbuild --root $(NPING_STAGING_DIR) --identifier org.insecure.nmap.nping --version $(NMAP_VERSION) --install-location /usr/local nping.pkg + pkgbuild --root $(NMAP_STAGING_DIR) --identifier org.insecure.nmap --version $(NMAP_VERSION) --install-location /Applications nmap.pkg + pkgbuild --root $(NCAT_STAGING_DIR) --identifier org.insecure.nmap.ncat --version $(NMAP_VERSION) --install-location /Applications ncat.pkg + pkgbuild --root $(NDIFF_STAGING_DIR) --identifier org.insecure.nmap.ndiff --version $(NMAP_VERSION) --install-location /Applications ndiff.pkg + pkgbuild --root $(NPING_STAGING_DIR) --identifier org.insecure.nmap.nping --version $(NMAP_VERSION) --install-location /Applications nping.pkg pkgbuild --root $(ZENMAP_STAGING_DIR) --identifier org.insecure.nmap.zenmap --version $(NMAP_VERSION) --install-location /Applications zenmap.pkg # Produce a .xml with packages information @@ -111,69 +103,53 @@ $(IMAGE_STAGING_DIR)/$(PKG_NAME): check-nmap check-ncat check-ndiff check-zenmap mv $(NAME_VERSION).mpkg $(NAME_VERSION)/$(NAME_VERSION).mpkg check-%: stage-% - (find $*-root -perm -a+x -type f | xargs otool -L | awk '/:$$/{e=$$0}index($$0,"$(JHBUILD_PREFIX)"){x=1;print e; print}END{exit x}') && echo "Libs are clean" + (find $*.app -perm -a+x -type f | xargs otool -L | awk '/:$$/{e=$$0}index($$0,"$(JHBUILD_PREFIX)"){x=1;print e; print}END{exit x}') && echo "Libs are clean" + (find $*.app -perm -a+x -type f -exec otool -l {} \; | awk '/:$$/{e=$$0}$$1=="minos"&&$$2!="$(OSX_MIN_VERSION)"{x=1;print e; print}END{exit x}' ) && echo "Bins are clean" + +check-zenmap: stage-zenmap + (find $(ZENMAP_BUILD_DIR) -perm -a+x -type f | xargs otool -L | awk '/:$$/{e=$$0}index($$0,"$(JHBUILD_PREFIX)"){x=1;print e; print}END{exit x}') && echo "Libs are clean" + (find $(ZENMAP_BUILD_DIR) -perm -a+x -type f -exec otool -l {} \; | awk '/:$$/{e=$$0}$$1=="minos"&&$$2!="$(OSX_MIN_VERSION)"{x=1;print e; print}END{exit x}' ) && echo "Bins are clean" export-%: rm -rf $* # Using @BASE discards local changes. svn export .. $* -export-tarball: +NMAP_TARBALL=$(JHBUILD_SOURCE)/pkgs/nmap-$(NMAP_VERSION).tar.gz +$(NMAP_TARBALL): rm -rf nmap-$(NMAP_VERSION) svn export .. nmap-$(NMAP_VERSION) tar czf nmap-$(NMAP_VERSION).tar.gz nmap-$(NMAP_VERSION) cp nmap-$(NMAP_VERSION).tar.gz $(JHBUILD_SOURCE)/pkgs/ -xstage-nmap: export-$(NMAP_BUILD_DIR) - cd $(NMAP_BUILD_DIR) && ./configure --without-zenmap --without-ncat --without-ndiff --without-nping --with-openssl="$(JHBUILD_PREFIX)" --with-libz="$(JHBUILD_PREFIX)" $(CONFIGURE_ARGS) - # LIB* is libssh2's name for *_LIBS - make -C $(NMAP_BUILD_DIR) OPENSSL_LIBS="$(OPENSSL_STATIC)" LIBSSL="$(OPENSSL_STATIC)" ZLIB_LIBS="$(LIBZ_STATIC)" LIBZ="$(LIBZ_STATIC)" - rm -rf $(NMAP_STAGING_DIR) - make -C $(NMAP_BUILD_DIR) install DESTDIR="`pwd`/$(NMAP_STAGING_DIR)" OPENSSL_LIBS="$(OPENSSL_STATIC)" ZLIB_LIBS="$(LIBZ_STATIC)" - -xstage-ncat: export-$(NCAT_BUILD_DIR) - cd $(NCAT_BUILD_DIR) && ./configure --without-zenmap --with-ncat --without-ndiff --without-nping --with-openssl="$(JHBUILD_PREFIX)" $(CONFIGURE_ARGS) - make -C $(NCAT_BUILD_DIR) build-ncat OPENSSL_LIBS="$(OPENSSL_STATIC)" - rm -rf $(NCAT_STAGING_DIR) - make -C $(NCAT_BUILD_DIR) install-ncat DESTDIR="`pwd`/$(NCAT_STAGING_DIR)" OPENSSL_LIBS="$(OPENSSL_STATIC)" - -xstage-nping: export-$(NPING_BUILD_DIR) - cd $(NPING_BUILD_DIR) && ./configure --without-zenmap --without-ncat --without-ndiff --with-nping --with-openssl="$(JHBUILD_PREFIX)" $(CONFIGURE_ARGS) - make -C $(NPING_BUILD_DIR) build-nping OPENSSL_LIBS="$(OPENSSL_STATIC)" - rm -rf $(NPING_STAGING_DIR) - make -C $(NPING_BUILD_DIR) install-nping DESTDIR="`pwd`/$(NPING_STAGING_DIR)" OPENSSL_LIBS="$(OPENSSL_STATIC)" - openssl.modules: ../nmap.h sed -i.bak '/ENTITY nmap_version/s/\".*\"/\"$(NMAP_VERSION)\"/' $@ -stage-%: export-tarball openssl.modules +clean-%: openssl.modules + jhbuild -m "file://`pwd`/openssl.modules" uninstall $* + +build-%: $(NMAP_TARBALL) openssl.modules jhbuild -m "file://`pwd`/openssl.modules" build $* - rm -rf $*-root - mkdir $*-root - rsync -a --files-from "$(JHBUILD_PREFIX)/_jhbuild/manifests/$*" "$(JHBUILD_PREFIX)" $*-root/ + +stage-%: build-% + sh make-app.sh $* "$(JHBUILD_PREFIX)" stage-zenmap: export-$(ZENMAP_BUILD_DIR) cd $(ZENMAP_BUILD_DIR)/zenmap && jhbuild run install_scripts/macosx/make-bundle.sh - rm -rf $(ZENMAP_STAGING_DIR) - mkdir -p $(ZENMAP_STAGING_DIR) - cp -rf $(ZENMAP_BUILD_DIR)/zenmap/dist/Zenmap.app $(ZENMAP_STAGING_DIR) -stage-ndiff: export-$(NDIFF_BUILD_DIR) - mkdir -p $(NDIFF_STAGING_DIR)/usr/local/bin - mkdir -p $(NDIFF_STAGING_DIR)/usr/local/share/man/man1 - cp $(NDIFF_BUILD_DIR)/ndiff/ndiff.py $(NDIFF_STAGING_DIR)/usr/local/bin/ndiff - cp $(NDIFF_BUILD_DIR)/ndiff/docs/ndiff.1 $(NDIFF_STAGING_DIR)/usr/local/share/man/man1/ +build-ndiff: + echo Nothing to do LICENSE.formatted: # Use the license formatter from the Windows installer. ../mswin32/license-format/licformat.sh ../LICENSE > $@ -clean: +clean: clean-nmap clean-ncat clean-nping rm -rf $(IMAGE_STAGING_DIR) rm -rf $(NMAP_BUILD_DIR) rm -rf $(NMAP_STAGING_DIR) rm -rf $(ZENMAP_BUILD_DIR) - rm -rf $(ZENMAP_STAGING_DIR) + #rm -rf $(ZENMAP_STAGING_DIR) rm -rf $(NCAT_BUILD_DIR) rm -rf $(NCAT_STAGING_DIR) rm -rf $(NDIFF_BUILD_DIR) diff --git a/macosx/README.md b/macosx/README.md index c79fdb32d..acddfac94 100644 --- a/macosx/README.md +++ b/macosx/README.md @@ -32,7 +32,7 @@ In order to compile, build and run Nmap on Mac OS, you will requiere the followi 1. **Jhbuild** for bundling and dependencies (see the [BUNDLING file](../BUNDLING.md)) 2. **Xcode** for Mac OS 10.8 or later ([https://developer.apple.com/xcode](https://developer.apple.com/xcode/)) -3. **Xcode Command-line Tools** for Mac OS 10.8 or later ([https://developer.apple.com/downloads](https://developer.apple.com/downloads/) — then download the latest version compatible with your OS version) +3. **Xcode Command-line Tools** for Mac OS 10.8 or later ([https://developer.apple.com/downloads](https://developer.apple.com/downloads/) then download the latest version compatible with your OS version) ## Installation @@ -81,7 +81,7 @@ The **bundling** process is as follows: After the bundling process is done and the app is installed, the **execution** path is as follows: -**Zenmap (zenmap_auth) —> zenmap.bin (launcher.sh) —> python zenmap.py** +**Zenmap (zenmap_auth) > zenmap.bin (launcher.sh) > python zenmap.py** ## Repositories and Troubleshooting diff --git a/macosx/launcher.sh b/macosx/launcher.sh new file mode 100755 index 000000000..aa1e9ebef --- /dev/null +++ b/macosx/launcher.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +name=`basename "$0"` +bundle=$(cd `dirname "$0"`;pwd)/../.. +bundle_contents="$bundle"/Contents +bundle_res="$bundle_contents"/Resources +bundle_lib="$bundle_res"/lib +bundle_bin="$bundle_res"/bin +bundle_data="$bundle_res"/share +bundle_etc="$bundle_res"/etc + +export DYLD_LIBRARY_PATH="$bundle_lib" +# Strip out the argument added by the OS. +if /bin/expr "x$1" : "x-psn_.*" > /dev/null; then + shift 1 +fi + +exec "$bundle_bin"/"$name" "$@" diff --git a/macosx/make-app.sh b/macosx/make-app.sh new file mode 100644 index 000000000..d2888776a --- /dev/null +++ b/macosx/make-app.sh @@ -0,0 +1,111 @@ +#!/bin/sh +set -x +set -e + +if [ "x$1" == "x" ]; then + echo "Need a name" + exit 1 +fi +package=$1 + +if [ "x$2" == "x" ]; then + echo "Need a JHBUILD_PREFIX" + exit 1 +fi +JHBUILD_PREFIX=$2 + +bundle=$package.app +bundle_contents="$bundle"/Contents +bundle_res="$bundle_contents"/Resources +bundle_lib="$bundle_res"/lib +bundle_bin="$bundle_res"/bin +bundle_data="$bundle_res"/share + +function do_lib() { + libname=$1 + grep '^lib/.*\.dylib$' "$JHBUILD_PREFIX/_jhbuild/manifests/$libname" >/tmp/$libname.libs + rsync -avu --files-from /tmp/$libname.libs "$JHBUILD_PREFIX/" "$bundle_res" +} + +ESCAPED_PREFIX=$(echo "$JHBUILD_PREFIX" | sed 's/\([\/\\.]\)/\\\1/g') +function run_install_name_tool() { + bin=$1 + otool -L "$bin" | awk "/$ESCAPED_PREFIX/{print \$1}" | while read dep; do + install_name_tool -change $dep $(echo $dep | sed "s/$ESCAPED_PREFIX\/lib/@executable_path\/..\/lib/") "$bin" + done +} + +function do_jhbuild_app() { + do_lib openssl + cp launcher.sh "$bundle_contents"/MacOS/$package + rsync -avu --files-from "$JHBUILD_PREFIX/_jhbuild/manifests/$package" "$JHBUILD_PREFIX/" "$bundle_res" +} + +mkdir -p "$bundle_res" +mkdir -p "$bundle_contents"/MacOS + +APP_WEB_SITE=https://nmap.org/ +BUNDLE_ID=org.insecure.nmap +case "$package" in + nmap) + do_jhbuild_app + do_lib libpcap + do_lib libpcre2 + rm "$bundle_lib"/libpcre2-{16,32,posix}.* + do_lib libssh2 + do_lib zlib + run_install_name_tool "$bundle_bin"/nmap + ;; + ncat) + do_jhbuild_app + run_install_name_tool "$bundle_bin"/ncat + APP_WEB_SITE="${APP_WEB_SITE}ncat/" + BUNDLE_ID="${BUNDLE_ID}.ncat" + ;; + nping) + do_jhbuild_app + do_lib libpcap + run_install_name_tool "$bundle_bin"/nping + APP_WEB_SITE="${APP_WEB_SITE}nping/" + BUNDLE_ID="${BUNDLE_ID}.nping" + ;; + ndiff) + APP_WEB_SITE="${APP_WEB_SITE}ndiff/" + BUNDLE_ID="${BUNDLE_ID}.ndiff" + ln -sf '../Resources/ndiff.py' "$bundle_contents"/MacOS/ndiff + cp ../ndiff/ndiff.py "$bundle_res/" + cp ../ndiff/docs/ndiff.1 "$bundle_res/" + ;; + *) + echo "Invalid package $package" + exit 2 + ;; +esac + +echo "Filling out Info.plist" +export APP_WEB_SITE +export BUNDLE_ID +export package +python3 - "Info.plist.in" >"$bundle/Info.plist" <<'EOF' +import sys +from os import environ +from string import Template +with open(sys.argv[1],"r",encoding="utf-8") as f: + sys.stdout.write(Template(f.read()).substitute( + BUNDLE_IDENTIFIER=environ["BUNDLE_ID"], + BUNDLE_NAME=environ["package"].title(), + BUNDLE_EXE=environ["package"], + OSX_MIN_VERSION=environ["OSX_MIN_VERSION"], + VERSION=environ["NMAP_VERSION"], + APP_WEB_SITE=environ["APP_WEB_SITE"], + APP_COPYRIGHT="Copyright 1996-2025 Nmap Software LLC", + EXTRA_DICT_CONTENT="" + )) +EOF + +find "$bundle_lib" -type f -name '*.dylib' | while read so; do + run_install_name_tool "$so" + # This isn't truly necessary, but it allows us to do a simpler check for problems later. + dep=$(basename "$so") + install_name_tool -id "@executable_path/../lib/$dep" "$so" +done diff --git a/macosx/openssl.modules b/macosx/openssl.modules index 372b6f0e5..7d114d93c 100644 --- a/macosx/openssl.modules +++ b/macosx/openssl.modules @@ -1,24 +1,40 @@ - + + + + ]> - + - + + + + + + + + + + + + + + + + - - + + + + @@ -55,23 +71,31 @@ + + + + + + + + + + -