Build Moonshot from source on macOS (with macOS Identity Selector)
The Moonshot source code is available from our GIT repository and it all can be built by hand relatively easily, assuming you have all of the prerequisite packages installed. This page has instructions for building the software itself.
Contents
macOS versions
These instructions have been tested on macOS 10.13 High Sierra and later.
1. System Preparation
1.1. Requirements
To build all of the Moonshot components, you need various packages installed. To install all of these, see below.
1.1.1. Get Xcode for macOS
To get all of the requirements on your macOS platform, you will need to install Xcode and the Xcode command-line extensions:
Install Xcode from the Mac App Store.
Open a Terminal, then install the Xcode Command Line Tools. You will be prompted with a dialog to install the Command Line Tools after a 130MB download.
$ xcode-select --install
If you have never launched Xcode before, do so at least once, or run the following command in your Terminal window.
$ sudo xcodebuild -license
1.1.2. Get Packages for macOS
The Moonshot installer is built using Packages (http://s.sudre.free.fr/Software/Packages/about.html). Install it before trying to build the installer.
1.1.3. Install the GNU tools for macOS
You will need to install several GNU tools:
Install GNU m4:
curl -OL https://ftp.gnu.org/gnu/m4/m4-1.4.19.tar.xz \ && tar xf m4-1.4.19.tar.xz \ && cd m4-1.4.19 \ && ./configure \ && make \ && sudo make install
Install GNU Autoconf:
curl -OL http://ftpmirror.gnu.org/autoconf/autoconf-2.69.tar.gz \ && tar xfz autoconf-2.69.tar.gz \ && cd autoconf-2.69 \ && ./configure \ && make \ && sudo make install
Install GNU Automake:
curl -OL http://ftpmirror.gnu.org/automake/automake-1.15.tar.gz \ && tar xfz automake-1.15.tar.gz \ && cd automake-1.15 \ && ./configure \ && make \ && sudo make install
Install GNU Libtool:
curl -OL http://ftpmirror.gnu.org/libtool/libtool-2.4.6.tar.gz \ && tar xfz libtool-2.4.6.tar.gz \ && cd libtool-2.4.6 \ && ./configure \ && make && sudo make install
Install pkg-config
curl -OL http://pkgconfig.freedesktop.org/releases/pkg-config-0.29.2.tar.gz \ && tar xfz pkg-config-0.29.2.tar.gz \ && cd pkg-config-0.29.2 \ && ./configure --with-internal-glib \ && make && sudo make install
1.1.4. Install JSON from CPAN
Update CPAN and install JSON:
# This is to make sure CPAN is configured if this is the first time you execute it sudo cpan -l sudo cpan install JSON
2. Setting build parameters and locations
Just like on Linux, build and installation locations matter, with one vital difference. On macOS, the /usr
tree itself is locked down and inaccessible, even for the privileged (root) user. However, locations like /usr/local
are open, and with newer versions of the OS, expect this to change.
For the purposes of this set of instructions, we recommend the following:
- For all the Moonshot dependencies, including Moonshot itself, the
--prefix
parameter should be set to/usr/local/moonshot
.
If you decide to change this location, you should appropriately change the locations in the commands in Sections 3 and 5 to your preference. - We recommend that you build all libraries with the
-rpath
parameter enabled for all libraries to avoid any clashes with other libraries (such as the older version of OpenSSL that macOS ships for compatibility reasons). We have been assured by macOS developers that theclang
andlibtool
tools for macOS support this. - We do NOT recommend using the Apple-provided sources for some libraries (such as Heimdal) as they have various customisations that may negatively impact how Moonshot works, and because Apple categorically WILL NOT support any of their own source sets (we've tried through a Platinum support path and had the support ticket closed and refunded).
If you DO try using Apple's OpenSource sources and find that things build and function fine, please let us know by commenting on this document (with instructions that we can update this document with). These instructions should generally be backward-compatible.
3. Download and build the required external dependencies
3.1.1. Gettext
curl -OL http://ftpmirror.gnu.org/gettext/gettext-0.20.1.tar.xz \ && tar xfz gettext-0.20.1.tar.xz \ && cd gettext-0.20.1 \ && ./configure --prefix /usr/local/moonshot \ && make && sudo make install
3.1.2. PCRE
PCRE is required during the build of some later dependencies. Libffi is one of these.
curl -OL https://downloads.sourceforge.net/project/pcre/pcre/8.45/pcre-8.45.tar.bz2 \ && tar xfz pcre-8.45.tar.bz2 \ && cd pcre-8.45 \ && ./configure --disable-dependency-tracking --enable-utf8 --enable-pcre8 --enable-pcre16 \ --enable-pcre32 --enable-unicode-properties --enable-pcregrep-libz --enable-pcregrep-libbz2 \ --enable-jit --prefix /usr/local/moonshot \ && make && sudo make install
3.1.3. Libffi
Libffi is a dependency of the Glib library that in turn is used by the Moonshot library for some Dbus functionality
curl -OL https://sourceware.org/pub/libffi/libffi-3.2.1.tar.gz \ && tar xfz libffi-3.2.1.tar.gz \ && cd libffi-3.2.1 \ && ./configure --disable-debug --disable-dependency-tracking --prefix /usr/local/moonshot \ && make && sudo make install
3.1.4. OpenSSL
curl -OL https://www.openssl.org/source/openssl-1.1.1m.tar.gz \ && tar xfz openssl-1.1.1m.tar.gz \ && cd openssl-1.1.1m \ && ./Configure --prefix=/usr/local/moonshot --openssldir=/usr/local/moonshot/bin threads \ shared zlib no-hw no-idea enable-rc5 enable-mdc2 enable-seed darwin64-x86_64-cc \ && make && sudo make install
3.1.5. Heimdal
Heimdal requires OpenSSL. Once OpenSSL has built successfully, build Heimdal.
We can safely use an old version (7.3.0) since runtime GSS libraries are taken from the system installation, and newer versions seem to generate invalid moonshot binaries.
curl -OL https://github.com/heimdal/heimdal/releases/download/heimdal-7.3.0/heimdal-7.3.0.tar.gz \ && tar xfz heimdal-7.3.0.tar.gz \ && cd heimdal-7.3.0 \ && CFLAGS="-I /usr/local/moonshot/include" \ ./configure --prefix=/usr/local/moonshot \ && make && sudo make install
3.1.6. LibConfuse
curl -OL https://github.com/martinh/libconfuse/releases/download/v3.2.2/confuse-3.2.2.tar.gz \ && tar xfz confuse-3.2.2.tar.gz \ && cd confuse-3.2.2 \ && LDFLAGS=" -L/usr/local/moonshot/lib -Wl,-rpath,/usr/local/moonshot/lib " \ ./configure --prefix=/usr/local/moonshot \ && make && sudo make install
3.1.7. LibEvent
Libevent requires OpenSSL. Once OpenSSL has built successfully, build Libevent.
curl -OL https://github.com/libevent/libevent/releases/download/release-2.1.11-stable/libevent-2.1.11-stable.tar.gz \ && tar xfz libevent-2.1.11-stable.tar.gz \ && cd libevent-2.1.11-stable \ && CFLAGS=" -I/usr/local/moonshot/include " LDFLAGS=" -L/usr/local/moonshot/lib -Wl,-rpath,/usr/local/moonshot/lib "\ ./configure --prefix=/usr/local/moonshot \ && make && sudo make install
3.1.8. Dbus
Dbus is used by the macOS client to communicate with the Moonshot mechanism.
curl -OL https://dbus.freedesktop.org/releases/dbus/dbus-1.12.16.tar.gz \ && tar xfz dbus-1.12.16.tar.gz \ && cd dbus-1.12.16 \ && EXPAT_CFLAGS=" -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include" \ EXPAT_LIBS="-lexpat" XML_CATALOG_FILES=/etc/xml/catalog TMPDIR=/tmp \ ./configure --disable-dependency-tracking --prefix=/usr/local/moonshot --sysconfdir=/etc \ --disable-xml-docs --disable-doxygen-docs --enable-launchd --with-launchd-agent-dir=/usr/local/moonshot \ --without-x --disable-tests \ && make && sudo make install # Disable EXTERNAL authentication that fails in MacOS with GDBUS sudo sed -i .bak "s/<auth>EXTERNAL<\/auth>//g" /usr/local/moonshot/share/dbus-1/session.conf
3.1.9. Glib
Glib is required by the Moonshot library.
curl -OL https://download.gnome.org/sources/glib/2.58/glib-2.58.3.tar.xz \ && tar fx glib-2.58.3.tar.xz \ && cd glib-2.58.3 \ && PATH=/usr/local/moonshot/bin:$PATH PKG_CONFIG_PATH=/usr/local/moonshot/lib/pkgconfig \ LDFLAGS=" -L/usr/local/moonshot/lib -Wl,-rpath,/usr/local/moonshot/lib " \ CFLAGS=" -I/usr/local/moonshot/include" \ sh autogen.sh --disable-maintainer-mode --disable-dependency-tracking --disable-silent-rules \ --disable-dtrace --disable-libelf --enable-static --prefix=/usr/local/moonshot \ --localstatedir=/var --with-gio-module-dir=/usr/local/moonshot/lib/gio/modules \ && make && sudo make install
3.1.10. Jansson
Jansson is used by the Moonshot libraries.
curl -OL http://www.digip.org/jansson/releases/jansson-2.12.tar.gz \ && tar xfz jansson-2.12.tar.gz \ && cd jansson-2.12 \ && LDFLAGS=" -L/usr/local/moonshot/lib -Wl,-rpath,/usr/local/moonshot/lib " CFLAGS=" -I/usr/local/moonshot/include " \ ./configure --prefix=/usr/local/moonshot --with-sysroot=/usr/local/moonshot \ && make && sudo make install
3.1.11. libxml2
libxml2 is used to parse assertions
curl -OL ftp://xmlsoft.org/libxml2/libxml2-2.9.10.tar.gz \ && tar xfz libxml2-2.9.10.tar.gz \ && cd libxml2-2.9.10 \ && ./configure --prefix=/usr/local/moonshot --without-python \ && make && sudo make install
4. Checkout the Moonshot source
The Moonshot source code is all stored in a GIT repository at https://github.com/janetuk.
5. Build Moonshot
5.1. Libradsec
Libradsec is used by the Moonshot libraries.
git clone https://github.com/janetuk/libradsec.git \ && cd libradsec \ && sh autogen.sh \ && LDFLAGS=" -L/usr/local/moonshot/lib -Wl,-rpath,/usr/local/moonshot/lib " \ CFLAGS=" -I/usr/local/moonshot/include -Wno-tautological-compare" \ ./configure --prefix=/usr/local/moonshot \ && make && sudo make install
5.2. The Moonshot UI
The Moonshot UI contains two components, libmoonshot, which is the interface between the Moonshot mechanism and the Identity Selector, and the Identity Selector itself. Libmoonshot and the Identity Selector can be built together:
Clone the Moonshot UI project:
git clone https://github.com/janetuk/moonshot-ui.git \ && cd moonshot-ui \ && PATH=/usr/local/moonshot/bin:$PATH PKG_CONFIG_PATH=/usr/local/moonshot/lib/pkgconfig \ LDFLAGS=" -L/usr/local/moonshot/lib -Wl,-rpath,/usr/local/moonshot/lib "\ DBUS_DAEMON="/usr/local/moonshot/bin/dbus-daemon" \ sh autogen.sh --prefix=/usr/local/moonshot
Apple Developer Team ID support
Optionally, if you have multiple Apple Developer ID certificates for different teams installed, use the optional
--with-apple-developer-id=DeveloperTeamID
parameter to specify the ID that is shown in brackets in the certificates. The build currently does not support Mac Developer certificates.To disable Apple Developer Team ID checks and signing, specify
--with-apple-developer-id=no
Build Libmoonshot:
make && sudo make install sudo cp /usr/local/moonshot/share/moonshot-ui/dbus/org.janet.Moonshot.service /usr/local/moonshot/share/dbus-1/services
Pay attention to the output the
sudo make install
command provides and double-check that the library exists in/usr/local/moonshot/lib
.Build the Identity Selector:
make app-bundle
- The Moonshot app will be in the
ui/macos-ui/build/Release
directory. You can then copy it from there to the/Applications
folder.
Identity Selector app signing
Currently the Identity Selector is not signed. This is to avoid limitations with macOS sandboxing. However, once we enable signing for the Identity Selector, you should see follow these additional steps:
Pay attention to the output the
make app-bundle
command provides. You should see something similar to this to show that the build has copied the entitlements and has signed the application:ProcessProductPackaging "" build/Moonshot.build/Release/Moonshot.build/Moonshot.app.xcent cd /.../macos-ui Entitlements: { "com.apple.security.app-sandbox" = 1; "com.apple.security.files.downloads.read-only" = 1; "com.apple.security.files.user-selected.read-only" = 1; } builtin-productPackagingUtility -entitlements -format xml -o macos-ui/build/Moonshot.build/Release/Moonshot.build/Moonshot.app.xcent CodeSign build/Release/Moonshot.app cd /.../macos-ui export CODESIGN_ALLOCATE=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/codesign_allocate Signing Identity: "Developer ID Application: <your Apple Developer ID Application signing certificate CN here>"
If Xcode did not sign the code and you did not disable Apple Developer ID checks and signing in Step 2, sign it manually:
moonshot-ui$ codesign --force --sign "<your Apple Developer ID Application signing certificate CN here>" "macos-ui/build/Release/Moonshot.app"
If you disabled Apple Developer ID checks in Step 2, skip this step. Otherwise verify the signing with the following command; you should have lines like these:
moonshot-ui$ codesign -dv --verbose=4 "macos-ui/build/Release/Moonshot.app" : Authority=Developer ID Certification Authority Authority=Apple Root CA Signed Time=16 Jan 2019, 11:24:21 Info.plist entries=24 TeamIdentifier=<your Apple Developer team ID here> :
5.3. The Moonshot mechanism
git clone https://github.com/janetuk/mech_eap.git \ && cd mech_eap \ && sh autogen.sh \ && CPPFLAGS=" -I/usr/local/moonshot/include " LIBS=" -L/usr/local/moonshot/lib " \ LDFLAGS=" -L/usr/local/moonshot/lib -Wl,-rpath,/usr/local/moonshot/lib " \ COMPILE_ET="/Users/$USER/moonshot/heimdal-7.3.0/lib/com_err/compile_et" \ ./configure --with-opensaml=no --with-shibresolver=no --with-shibsp=no \ --sysconfdir=/etc --prefix=/usr/local/moonshot \ && make && sudo make install
Configure script parameters
There are several parameters in the command above that rely on locations noted down previously:
COMPILE_ET
contains the full path to the compile_et
binary that will be in your Heimdal build tree. You noted this down in the last step of Section 3.1.5.
You should now have a mech_eap.so
file in /usr/local/moonshot/lib/gss
.
6. Test Moonshot
To test this build of Moonshot, you will need to make some privileged changes to the system you built this on:
In
/etc
, create agss
directory:$ sudo mkdir -p /etc/gss
Copy the
mech
file from the Moonshotmech_eap
build directory to/etc/gss
$ sudo cp mech_eap/mech /etc/gss/
- As the privileged user, edit the
/etc/gss/mech
file:- Change the
mech_eap.so
entry on each line to the full path of the library, e.g./usr/local/moonshot/lib/gss/mech_eap.so
- Save the file.
- Change the
Copy the Identity Selector app (Moonshot.app) you built in Step 2 of Section 5.2 above into the /Applications folder.
- Run the Identity Selector app from the Launch Pad, then add a new Moonshot identity to the app.
Run an SSH command to a Moonshot-enabled system that the credentials you added in the previous step will be valid for:
ssh -Kv user@moonshot-host.realm
Jisc Assent
If you have an identity provider on the Jisc Assent network, you can use
ssh -Kv moonshot@test-sp.infr.assent.ti.ja.net
to test whether your macOS Moonshot mechanism worked successfully.You should be prompted for an identity the first time you do this, and then successfully connect to the service. You should see several lines like this in the output:
debug1: SSH2_MSG_SERVICE_REQUEST sent debug1: SSH2_MSG_SERVICE_ACCEPT received debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password debug1: Delegating credentials debug1: Delegating credentials debug1: Delegating credentials debug1: Delegating credentials debug1: Delegating credentials debug1: Delegating credentials debug1: Delegating credentials debug1: Delegating credentials debug1: Delegating credentials debug1: Delegating credentials debug1: Delegating credentials debug1: Authentication succeeded (gssapi-with-mic). Authenticated to test-sp.infr.assent.ti.ja.net ([3.9.92.102]:22). debug1: channel 0: new [client-session] debug1: Requesting no-more-sessions@openssh.com debug1: Entering interactive session. debug1: Sending environment. debug1: Sending env LANG = en_GB.UTF-8
Jisc Assent
On the Jisc Assent Test SSH Service, the final output for success will be this:
debug1: Entering interactive session. debug1: Sending environment. debug1: Sending env LANG = en_GB.UTF-8 *** JISC Moonshot Test SSH Server *** You have successfully logged in with Moonshot. You are user: moonshot [moonshot@ssh ~]$
7. Distribute and install Moonshot
To distribute this binary set, you will need to trim down the binaries you have built to include only the dynamic libraries and only bare essentials needed to run the mechanism:
7.1. Automatic build
The macos-ui
directory in the moonshot-ui/
tree has a Makefile that will automatically run all the build steps in Section 7.2.
- Change to the
macos-ui
directory, runmake installer
. - The final result should be a signed (if you chose to use Apple Developer ID support)
Moonshot.dmg
file in themacos-ui
directory.
7.2. Manual build
7.2.1. Create the distribution archive for the mechanism
Make a tarball with the required libraries and binaries from the
/usr/local/moonshot
directory into the Installer directory as the privileged user. Thefilemanifest.txt
file contains the full list of required files.cd Installer && sudo tar -zcvf local.tar.gz -C /usr/local/ $(cat ../filemanifest.txt)
7.2.2. The Moonshot Uninstaller utility
The Uninstaller utility is an Xcode project.
Build the Uninstaller utility:
moonshot-ui$ make uninstaller-bundle
Pay attention to the output the
make uninstaller-bundle
command provides. You should see something similar to this to show that the build has copied the entitlements and has signed the application:ProcessProductPackaging "" build/Uninstall\ Moonshot.build/Release/Uninstall\ Moonshot.build/Uninstall\ Moonshot.app.xcent cd /.../macos-ui/Uninstaller Entitlements: { "com.apple.security.app-sandbox" = 0; "com.apple.security.files.user-selected.read-only" = 0; } builtin-productPackagingUtility -entitlements -format xml -o /.../macos-ui/Uninstaller/build/Uninstall\ Moonshot.build/Release/Uninstall\ Moonshot.build/Uninstall\ Moonshot.app.xcent CodeSign build/Release/Uninstall\ Moonshot.app cd /.../macos-ui/Uninstaller export CODESIGN_ALLOCATE=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/codesign_allocate Signing Identity: "Developer ID Application: <your Apple Developer ID Application signing certificate CN here>"
If Xcode did not sign the code and you did not disable Apple Developer ID checks in Section 5.2, Step 2, sign it manually:
moonshot-ui$ codesign --force --sign "<your Apple Developer ID Application signing certificate CN here>" "macos-ui/build/Release/Uninstall Moonshot.app"
Verify the signing with the following command; you should have lines like these:
moonshot-ui$ codesign -dv --verbose=4 "macos-ui/Uninstaller/build/Release/Uninstall Moonshot.app" : Authority=Developer ID Certification Authority Authority=Apple Root CA Signed Time=16 Jan 2019, 11:24:21 Info.plist entries=24 TeamIdentifier=<your Apple Developer team ID here> :
The
Uninstall Moonshot
app will be in theui/macos-ui/Uninstaller/build/Release
directory. You can then copy it from there to the/Applications
folder.
7.2.3. The Moonshot Installer
The Moonshot installer contains the distribution archive, the uninstaller utility, and the Moonshot identity selector.
Change to the Installer folder:
$ cd ui/macos-ui/Installer
- Copy the Moonshot identity selector app from the Applications folder to the
LatestBuild
directory - Copy the Uninstall Moonshot app from the
ui/macos-ui/Uninstaller/build/Release
directory to theLatestBuild
directory - Copy the distribution archive you created in Section 8.1 to this directory, replacing the existing
local.tar.gz
file. Build the installer:
Installer$ mkdir Moonshot Installer$ packagesbuild Moonshot.pkgproj Installer$ productsign --sign "<your Apple Developer ID Installer signing certificate CN here>" Moonshot.pkg Moonshot/Moonshot.pkg
Create the Moonshot distribution disk image:
Installer$ chmod +x create-dmg.sh Installer$ create-dmg.sh --volname "Moonshot" \ --volicon moonshot-dmg-volumeicons.icns \ --background moonshot-dmg-background-with-start.png \ --no-internet-enable --window-size 400 273 --icon-size 64 --text-size 14 \ --icon "Moonshot.pkg" 160 48 --hide-extension "Moonshot.pkg" \ Moonshot.dmg Moonshot/ Installer$ codesign --sign "<your Apple Developer ID Application signing certificate CN here>" Moonshot.dmg
- Copy the resulting
Moonshot.dmg
to your distribution point. Generate a checksum for
Moonshot.dmg
with the following command:$ shasum -a 256 Moonshot.dmg
8. Issues
Current issues with this build include that the macOS SSH client abandons any gssapi-with-mic
conversations if the first mechanism it chooses, fails.
In a domain environment, this usually involves a Kerberos interaction, i.e. where you have received a Kerberos ticket before by logging in or by running kinit
. Other ssh clients (or a custom build of the ssh client) may not exhibit this behaviour.
On macOS Sierra and later, the native SSH client is sandboxed when run from its default location in /usr/bin
. Making a copy of the binary in /usr/local/bin
enables it to authenticate with Moonshot. Adjust /etc/paths
to load binaries in /usr/local/bin
first, then restart your sessions.
Currently the Moonshot Identity Manager (Moonshot.app) is not signed during the automatic build. This is due to Apple sandboxing the app when it is signed, making it impossible for it to communicate with Dbus (and by extension, the Moonshot mechanism). Not signing the app allows Moonshot authentication to proceed.
On MacOS BIg Sur and later, besides moving the binary you would also need to remove the signature, since signed binaries are sandboxed as well. Use codesign --remove-signature /usr/local/bin/ssh
to do so.