mirror of https://github.com/oxen-io/lokinet
commit
13c71c3626
@ -0,0 +1,64 @@
|
||||
|
||||
set(default_build_gui OFF)
|
||||
set(default_gui_target pack)
|
||||
if(APPLE)
|
||||
set(default_build_gui ON)
|
||||
set(default_gui_target macos:raw)
|
||||
elseif(WIN32)
|
||||
set(default_build_gui ON)
|
||||
set(default_gui_target win32)
|
||||
endif()
|
||||
|
||||
option(BUILD_GUI "build electron gui from 'gui' submodule source" ${default_build_gui})
|
||||
set(GUI_YARN_TARGET "${default_gui_target}" CACHE STRING "yarn target for building the GUI")
|
||||
set(GUI_YARN_EXTRA_OPTS "" CACHE STRING "extra options to pass into the yarn build command")
|
||||
|
||||
if (BUILD_GUI)
|
||||
message(STATUS "Building lokinet-gui")
|
||||
|
||||
find_program(YARN NAMES yarn yarnpkg REQUIRED)
|
||||
message(STATUS "Building lokinet-gui with yarn ${YARN}, target ${GUI_YARN_TARGET}")
|
||||
set(wine_env)
|
||||
if(WIN32)
|
||||
set(wine_env WINEDEBUG=-all "WINEPREFIX=${PROJECT_BINARY_DIR}/wineprefix")
|
||||
endif()
|
||||
|
||||
add_custom_target(lokinet-gui
|
||||
COMMAND ${YARN} install --frozen-lockfile &&
|
||||
${wine_env} ${YARN} ${GUI_YARN_EXTRA_OPTS} ${GUI_YARN_TARGET}
|
||||
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/gui")
|
||||
|
||||
if(APPLE)
|
||||
add_custom_target(assemble_gui ALL
|
||||
DEPENDS assemble lokinet-gui
|
||||
COMMAND mkdir "${PROJECT_BINARY_DIR}/Lokinet.app/Contents/Helpers"
|
||||
COMMAND cp -a "${PROJECT_SOURCE_DIR}/gui/release/mac/Lokinet-GUI.app" "${PROJECT_BINARY_DIR}/Lokinet.app/Contents/Helpers/"
|
||||
COMMAND mkdir -p "${PROJECT_BINARY_DIR}/Lokinet.app/Contents/Resources/en.lproj"
|
||||
COMMAND cp "${PROJECT_SOURCE_DIR}/contrib/macos/InfoPlist.strings" "${PROJECT_BINARY_DIR}/Lokinet.app/Contents/Resources/en.lproj/"
|
||||
COMMAND cp "${PROJECT_BINARY_DIR}/Lokinet.app/Contents/Resources/icon.icns" "${PROJECT_BINARY_DIR}/Lokinet.app/Contents/Helpers/Lokinet-GUI.app/Contents/Resources/icon.icns"
|
||||
COMMAND cp "${PROJECT_SOURCE_DIR}/contrib/macos/InfoPlist.strings" "${PROJECT_BINARY_DIR}/Lokinet.app/Contents/Helpers/Lokinet-GUI.app/Contents/Resources/en.lproj/"
|
||||
COMMAND /usr/libexec/PlistBuddy
|
||||
-c "Delete :CFBundleDisplayName"
|
||||
-c "Add :LSHasLocalizedDisplayName bool true"
|
||||
-c "Add :CFBundleDevelopmentRegion string en"
|
||||
-c "Set :CFBundleShortVersionString ${lokinet_VERSION}"
|
||||
-c "Set :CFBundleVersion ${lokinet_VERSION}.${LOKINET_APPLE_BUILD}"
|
||||
"${PROJECT_BINARY_DIR}/Lokinet.app/Contents/Helpers/Lokinet-GUI.app/Contents/Info.plist"
|
||||
)
|
||||
|
||||
elseif(WIN32)
|
||||
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/gui")
|
||||
add_custom_target(copy_gui ALL
|
||||
DEPENDS lokinet lokinet-gui
|
||||
# FIXME: we really shouldn't be building inside the source directory but this is npm...
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${PROJECT_SOURCE_DIR}/gui/release/Lokinet-GUI_portable.exe"
|
||||
"${PROJECT_BINARY_DIR}/gui/lokinet-gui.exe"
|
||||
)
|
||||
else()
|
||||
message(FATAL_ERROR "Building/bundling the GUI from this repository is not supported on this platform")
|
||||
endif()
|
||||
|
||||
else()
|
||||
message(STATUS "Not building lokinet-gui")
|
||||
endif()
|
@ -0,0 +1,176 @@
|
||||
if(NOT APPLE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
|
||||
option(MACOS_SYSTEM_EXTENSION
|
||||
"Build the network extension as a system extension rather than a plugin. This must be ON for non-app store release builds, and must be OFF for dev builds and Mac App Store distribution builds"
|
||||
OFF)
|
||||
option(CODESIGN "codesign the resulting app and extension" ON)
|
||||
set(CODESIGN_ID "" CACHE STRING "codesign the macos app using this key identity; if empty we'll try to guess")
|
||||
set(default_profile_type "dev")
|
||||
if(MACOS_SYSTEM_EXTENSION)
|
||||
set(default_profile_type "release")
|
||||
endif()
|
||||
set(CODESIGN_PROFILE "${PROJECT_SOURCE_DIR}/contrib/macos/lokinet.${default_profile_type}.provisionprofile" CACHE FILEPATH
|
||||
"Path to a .provisionprofile to use for the main app")
|
||||
|
||||
if(CODESIGN AND NOT CODESIGN_ID)
|
||||
if(MACOS_SYSTEM_EXTENSION)
|
||||
set(codesign_cert_pattern "Developer ID Application")
|
||||
else()
|
||||
set(codesign_cert_pattern "Apple Development")
|
||||
endif()
|
||||
execute_process(
|
||||
COMMAND security find-identity -v -p codesigning
|
||||
COMMAND sed -n "s/^ *[0-9][0-9]*) *\\([A-F0-9]\\{40\\}\\) *\"\\(${codesign_cert_pattern}.*\\)\"\$/\\1 \\2/p"
|
||||
RESULT_VARIABLE find_id_exit_code
|
||||
OUTPUT_VARIABLE find_id_output)
|
||||
if(NOT find_id_exit_code EQUAL 0)
|
||||
message(FATAL_ERROR "Finding signing identities with security find-identity failed; try specifying an id using -DCODESIGN_ID=...")
|
||||
endif()
|
||||
|
||||
string(REGEX MATCHALL "(^|\n)[0-9A-F]+" find_id_sign_id "${find_id_output}")
|
||||
if(NOT find_id_sign_id)
|
||||
message(FATAL_ERROR "Did not find any \"${codesign_cert_pattern}\" identity; try specifying an id using -DCODESIGN_ID=...")
|
||||
endif()
|
||||
if (find_id_sign_id MATCHES ";")
|
||||
message(FATAL_ERROR "Found multiple \"${codesign_cert_pattern}\" identities:\n${find_id_output}\nSpecify an identify using -DCODESIGN_ID=...")
|
||||
endif()
|
||||
set(CODESIGN_ID "${find_id_sign_id}" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
|
||||
if(CODESIGN)
|
||||
message(STATUS "Codesigning using ${CODESIGN_ID}")
|
||||
|
||||
if (NOT MACOS_NOTARIZE_USER AND NOT MACOS_NOTARIZE_PASS AND NOT MACOS_NOTARIZE_ASC AND EXISTS "$ENV{HOME}/.notarization.cmake")
|
||||
message(STATUS "Loading notarization info from ~/.notarization.cmake")
|
||||
include("$ENV{HOME}/.notarization.cmake")
|
||||
endif()
|
||||
|
||||
if (MACOS_NOTARIZE_USER AND MACOS_NOTARIZE_PASS AND MACOS_NOTARIZE_ASC)
|
||||
message(STATUS "Enabling notarization with account ${MACOS_NOTARIZE_ASC}/${MACOS_NOTARIZE_USER}")
|
||||
else()
|
||||
message(WARNING "You have not set one or more of MACOS_NOTARIZE_USER, MACOS_NOTARIZE_PASS, MACOS_NOTARIZE_ASC: notarization will fail; see contrib/macos/README.txt")
|
||||
endif()
|
||||
|
||||
else()
|
||||
message(WARNING "Codesigning disabled; the resulting build will not run on most macOS systems")
|
||||
endif()
|
||||
|
||||
|
||||
if(NOT CODESIGN_PROFILE)
|
||||
message(WARNING "Missing a CODESIGN_PROFILE provisioning profile: Apple will most likely log an uninformative error message to the system log and then kill harmless kittens if you try to run the result")
|
||||
endif()
|
||||
if(NOT EXISTS "${CODESIGN_PROFILE}")
|
||||
message(FATAL_ERROR "Provisioning profile ${CODESIGN_PROFILE} does not exist; fix your -DCODESIGN_PROFILE path")
|
||||
endif()
|
||||
message(STATUS "Using ${CODESIGN_PROFILE} provisioning profile")
|
||||
|
||||
|
||||
if(MACOS_SYSTEM_EXTENSION)
|
||||
set(lokinet_ext_dir Contents/Library/SystemExtensions)
|
||||
else()
|
||||
set(lokinet_ext_dir Contents/PlugIns)
|
||||
endif()
|
||||
|
||||
if(CODESIGN)
|
||||
if(MACOS_SYSTEM_EXTENSION)
|
||||
set(LOKINET_ENTITLEMENTS_TYPE sysext)
|
||||
set(notarize_py_is_sysext True)
|
||||
else()
|
||||
set(LOKINET_ENTITLEMENTS_TYPE plugin)
|
||||
set(notarize_py_is_sysext False)
|
||||
endif()
|
||||
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/contrib/macos/sign.sh.in"
|
||||
"${PROJECT_BINARY_DIR}/sign.sh"
|
||||
@ONLY)
|
||||
|
||||
add_custom_target(
|
||||
sign
|
||||
DEPENDS "${PROJECT_BINARY_DIR}/sign.sh"
|
||||
COMMAND "${PROJECT_BINARY_DIR}/sign.sh"
|
||||
)
|
||||
|
||||
if(MACOS_NOTARIZE_USER AND MACOS_NOTARIZE_PASS AND MACOS_NOTARIZE_ASC)
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/contrib/macos/notarize.py.in"
|
||||
"${PROJECT_BINARY_DIR}/notarize.py"
|
||||
@ONLY)
|
||||
add_custom_target(
|
||||
notarize
|
||||
DEPENDS "${PROJECT_BINARY_DIR}/notarize.py" sign
|
||||
COMMAND "${PROJECT_BINARY_DIR}/notarize.py"
|
||||
)
|
||||
else()
|
||||
message(WARNING "You have not set one or more of MACOS_NOTARIZE_USER, MACOS_NOTARIZE_PASS, MACOS_NOTARIZE_ASC: notarization disabled")
|
||||
endif()
|
||||
else()
|
||||
add_custom_target(sign COMMAND "true")
|
||||
add_custom_target(notarize DEPENDS sign COMMAND "true")
|
||||
endif()
|
||||
|
||||
|
||||
# Called later to set things up, after the main lokinet targets are set up
|
||||
function(macos_target_setup)
|
||||
|
||||
if(MACOS_SYSTEM_EXTENSION)
|
||||
target_compile_definitions(lokinet PRIVATE MACOS_SYSTEM_EXTENSION)
|
||||
endif()
|
||||
|
||||
set_target_properties(lokinet
|
||||
PROPERTIES
|
||||
OUTPUT_NAME Lokinet
|
||||
MACOSX_BUNDLE TRUE
|
||||
MACOSX_BUNDLE_INFO_STRING "Lokinet IP Packet Onion Router"
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "Lokinet"
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION "${lokinet_VERSION}"
|
||||
MACOSX_BUNDLE_LONG_VERSION_STRING "${lokinet_VERSION}"
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "${lokinet_VERSION_MAJOR}.${lokinet_VERSION_MINOR}"
|
||||
MACOSX_BUNDLE_GUI_IDENTIFIER "org.lokinet"
|
||||
MACOSX_BUNDLE_INFO_PLIST "${PROJECT_SOURCE_DIR}/contrib/macos/lokinet.Info.plist.in"
|
||||
MACOSX_BUNDLE_COPYRIGHT "© 2022, The Oxen Project"
|
||||
)
|
||||
|
||||
add_custom_target(copy_bootstrap
|
||||
DEPENDS lokinet-extension
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PROJECT_SOURCE_DIR}/contrib/bootstrap/mainnet.signed
|
||||
$<TARGET_BUNDLE_DIR:lokinet-extension>/Contents/Resources/bootstrap.signed
|
||||
)
|
||||
|
||||
set(mac_icon ${PROJECT_BINARY_DIR}/lokinet.icns)
|
||||
add_custom_command(OUTPUT ${mac_icon}
|
||||
COMMAND ${PROJECT_SOURCE_DIR}/contrib/macos/mk-icns.sh ${PROJECT_SOURCE_DIR}/contrib/lokinet-mac.svg ${mac_icon}
|
||||
DEPENDS ${PROJECT_SOURCE_DIR}/contrib/lokinet.svg ${PROJECT_SOURCE_DIR}/contrib/macos/mk-icns.sh)
|
||||
add_custom_target(icon DEPENDS ${mac_icon})
|
||||
|
||||
|
||||
add_dependencies(lokinet lokinet-extension icon)
|
||||
|
||||
|
||||
if(CODESIGN_PROFILE)
|
||||
add_custom_target(copy_prov_prof
|
||||
DEPENDS lokinet
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CODESIGN_PROFILE}
|
||||
$<TARGET_BUNDLE_DIR:lokinet>/Contents/embedded.provisionprofile
|
||||
)
|
||||
else()
|
||||
add_custom_target(copy_prov_prof COMMAND true)
|
||||
endif()
|
||||
|
||||
add_custom_target(assemble ALL
|
||||
DEPENDS lokinet lokinet-extension icon copy_prov_prof copy_bootstrap
|
||||
COMMAND rm -rf "${PROJECT_BINARY_DIR}/Lokinet.app"
|
||||
COMMAND cp -a $<TARGET_BUNDLE_DIR:lokinet> "${PROJECT_BINARY_DIR}/Lokinet.app"
|
||||
COMMAND mkdir -p "${PROJECT_BINARY_DIR}/Lokinet.app/${lokinet_ext_dir}"
|
||||
COMMAND cp -a $<TARGET_BUNDLE_DIR:lokinet-extension> "${PROJECT_BINARY_DIR}/Lokinet.app/${lokinet_ext_dir}/"
|
||||
COMMAND mkdir -p "${PROJECT_BINARY_DIR}/Lokinet.app/Contents/Resources"
|
||||
COMMAND cp -a "${mac_icon}" "${PROJECT_BINARY_DIR}/Lokinet.app/Contents/Resources/icon.icns"
|
||||
)
|
||||
|
||||
if(CODESIGN)
|
||||
add_dependencies(sign assemble)
|
||||
endif()
|
||||
endfunction()
|
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 1024 1024" style="enable-background:new 0 0 1024 1024;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
</style>
|
||||
<g>
|
||||
<path class="st0" d="M897.5,1024H126.5C56.6,1024,0,967.4,0,897.5V126.5C0,56.6,56.6,0,126.5,0h771.1C967.4,0,1024,56.6,1024,126.5
|
||||
v771.1C1024,967.4,967.4,1024,897.5,1024z"/>
|
||||
</g>
|
||||
<g>
|
||||
<polygon points="585.2,658.9 512,732.1 438.8,658.9 365.1,732.1 512,879 658.9,732.1 "/>
|
||||
<polygon points="658.9,585.2 732.1,512 658.9,438.8 732.1,365.1 879,512 732.1,658.9 "/>
|
||||
<polygon points="365.1,438.8 291.9,512 365.1,585.2 291.9,658.9 145,512 291.9,365.1 "/>
|
||||
<polygon points="438.8,365.1 512,291.9 585.2,365.1 658.9,291.9 512,145 365.1,291.9 "/>
|
||||
<rect x="533.4" y="533.3" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -242.3375 585.3179)" width="103.9" height="103.9"/>
|
||||
<rect x="386.7" y="386.9" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -181.837 438.6521)" width="103.9" height="103.9"/>
|
||||
<rect x="533.2" y="386.7" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -138.7545 542.2352)" width="103.9" height="103.9"/>
|
||||
<rect x="386.9" y="533.5" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -285.4199 481.7348)" width="103.9" height="103.9"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
@ -1,24 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Lokinet</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>MacOS/lokinet</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.loki-project.lokinet</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>lokinet</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>@lokinet_VERSION@</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>@lokinet_VERSION@.@LOKINET_APPLE_BUILD@</string>
|
||||
</dict>
|
||||
</plist>
|
Binary file not shown.
@ -1,40 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Lokinet</string>
|
||||
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>lokinet-extension</string>
|
||||
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.loki-project.lokinet.network-extension</string>
|
||||
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
|
||||
<key>CFBundleName</key>
|
||||
<string>lokinet</string>
|
||||
|
||||
<key>CFBundleVersion</key>
|
||||
<string>@lokinet_VERSION@</string>
|
||||
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>11.0</string>
|
||||
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.networkextension.packet-tunnel</string>
|
||||
<key>NSExtensionPrincipalClass</key>
|
||||
<string>LLARPPacketTunnel</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
@ -1,38 +0,0 @@
|
||||
This directory contains the magical incantations and random voodoo symbols needed to coax an Apple
|
||||
build. There's no reason builds have to be this stupid, except that Apple wants to funnel everyone
|
||||
into the no-CI, no-help, undocumented, non-toy-apps-need-not-apply modern Apple culture.
|
||||
|
||||
This is disgusting.
|
||||
|
||||
But it gets worse.
|
||||
|
||||
The following two files, in particular, are the very worst manifestations of this already toxic
|
||||
Apple cancer: they are required for proper permissions to run on macOS, are undocumented, and can
|
||||
only be regenerated through the entirely closed source Apple Developer backend, for which you have
|
||||
to pay money first to get a team account (a personal account will not work), and they lock the
|
||||
resulting binaries to only run on individually selected Apple computers selected at the time the
|
||||
profile is provisioned (with no ability to allow it to run anywhere).
|
||||
|
||||
lokinet.provisionprofile
|
||||
lokinet-extension.provisionprofile
|
||||
|
||||
This is actively hostile to open source development, but that is nothing new for Apple.
|
||||
|
||||
In order to make things work, you'll have to replace these provisioning profiles with your own
|
||||
(after paying Apple for the privilege of developing on their platform, of course) and change all the
|
||||
team/application/bundle IDs to reference your own team, matching the provisioning profiles. The
|
||||
provisioning profiles must be a "macOS Development" provisioning profile, and must include the
|
||||
signing keys and the authorized devices on which you want to run it. (The profiles bundled in this
|
||||
repository contains the lokinet team's "Apple Development" keys associated with the Oxen project,
|
||||
and mac dev boxes. This is *useless* for anyone else).
|
||||
|
||||
Also take note that you *must not* put a development build `lokinet.app` inside /Applications
|
||||
because if you do, it won't work because *on top* of the ridiculous signing and entitlement bullshit
|
||||
that Apple makes you jump through, the rules *also* differ for binaries placed in /Applications
|
||||
versus binaries placed elsewhere, but like everything else here, it is entirely undocumented.
|
||||
|
||||
If you are reading this to try to build Lokinet for yourself for an Apple operating system and
|
||||
simultaneously care about open source, privacy, or freedom then you, my friend, are a walking
|
||||
contradiction: you are trying to get Lokinet to work on a platform that actively despises open
|
||||
source, privacy, and freedom. Even Windows is a better choice in all of these categories than
|
||||
Apple.
|
@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Lokinet Network Extension</string>
|
||||
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>org.lokinet.network-extension</string>
|
||||
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.lokinet.network-extension</string>
|
||||
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>SYSX</string>
|
||||
|
||||
<key>CFBundleName</key>
|
||||
<string>org.lokinet.network-extension</string>
|
||||
|
||||
<key>CFBundleVersion</key>
|
||||
<string>@lokinet_VERSION@.@LOKINET_APPLE_BUILD@</string>
|
||||
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>@lokinet_VERSION@</string>
|
||||
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.15</string>
|
||||
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2022 The Oxen Project, licensed under GPLv3-or-later</string>
|
||||
|
||||
<key>NSSystemExtensionUsageDescription</key>
|
||||
<string>Provides Lokinet Network connectivity.</string>
|
||||
|
||||
<key>NetworkExtension</key>
|
||||
<dict>
|
||||
<key>NEMachServiceName</key>
|
||||
<string>SUQ8J2PCT7.org.lokinet.network-extension</string>
|
||||
|
||||
<key>NEProviderClasses</key>
|
||||
<dict>
|
||||
<key>com.apple.networkextension.packet-tunnel</key>
|
||||
<string>LLARPPacketTunnel</string>
|
||||
|
||||
<key>com.apple.networkextension.dns-proxy</key>
|
||||
<string>LLARPDNSProxy</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.application-identifier</key>
|
||||
<string>SUQ8J2PCT7.org.lokinet.network-extension</string>
|
||||
|
||||
<key>com.apple.developer.networking.networkextension</key>
|
||||
<array>
|
||||
<string>packet-tunnel-provider-systemextension</string>
|
||||
<string>dns-proxy-systemextension</string>
|
||||
</array>
|
||||
|
||||
<key>com.apple.developer.team-identifier</key>
|
||||
<string>SUQ8J2PCT7</string>
|
||||
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>SUQ8J2PCT7.org.lokinet</string>
|
||||
</array>
|
||||
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
|
||||
<key>com.apple.security.network.server</key>
|
||||
<true/>
|
||||
|
||||
</dict>
|
||||
</plist>
|
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>Lokinet</string>
|
||||
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.lokinet</string>
|
||||
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
|
||||
<key>CFBundleName</key>
|
||||
<string>Lokinet</string>
|
||||
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>icon.icns</string>
|
||||
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>@lokinet_VERSION@</string>
|
||||
|
||||
<key>CFBundleVersion</key>
|
||||
<string>@lokinet_VERSION@.@LOKINET_APPLE_BUILD@</string>
|
||||
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.15</string>
|
||||
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2022 The Oxen Project, licensed under GPLv3-or-later</string>
|
||||
|
||||
<key>LSUIElement</key>
|
||||
<true/>
|
||||
|
||||
<key>LSHasLocalizedDisplayName</key>
|
||||
<true/>
|
||||
|
||||
</dict>
|
||||
</plist>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.application-identifier</key>
|
||||
<string>SUQ8J2PCT7.org.lokinet</string>
|
||||
|
||||
<key>com.apple.developer.networking.networkextension</key>
|
||||
<array>
|
||||
<string>packet-tunnel-provider-systemextension</string>
|
||||
<string>dns-proxy-systemextension</string>
|
||||
<string>dns-settings</string>
|
||||
</array>
|
||||
|
||||
<key>com.apple.developer.team-identifier</key>
|
||||
<string>SUQ8J2PCT7</string>
|
||||
|
||||
<key>com.apple.developer.system-extension.install</key>
|
||||
<true/>
|
||||
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>SUQ8J2PCT7.org.lokinet</string>
|
||||
</array>
|
||||
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
|
||||
<key>com.apple.security.network.server</key>
|
||||
<true/>
|
||||
|
||||
</dict>
|
||||
</plist>
|
@ -1,26 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>network.loki.lokinet.daemon</string>
|
||||
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/var/lib/lokinet/lokinet_macos_daemon_script.sh</string>
|
||||
</array>
|
||||
|
||||
<!-- Keep Lokinet alive unless magic file exists -->
|
||||
<key>KeepAlive</key>
|
||||
<dict>
|
||||
<key>PathState</key>
|
||||
<dict>
|
||||
<key>/var/lib/lokinet/suspend-launchd-service</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</dict>
|
||||
|
||||
<key>StandardOutPath</key>
|
||||
<string>/var/log/lokinet.log</string>
|
||||
</dict>
|
||||
</plist>
|
@ -1,10 +1,72 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
codesign --verbose=4 --force -s "@CODESIGN_APPEX@" \
|
||||
--entitlements "@PROJECT_SOURCE_DIR@/contrib/macos/lokinet-extension.entitlements.plist" \
|
||||
--deep --strict --timestamp --options=runtime "@SIGN_TARGET@/Contents/PlugIns/lokinet-extension.appex"
|
||||
for file in "@SIGN_TARGET@/Contents/MacOS/lokinet" "@SIGN_TARGET@" ; do
|
||||
codesign --verbose=4 --force -s "@CODESIGN_APP@" \
|
||||
--entitlements "@PROJECT_SOURCE_DIR@/contrib/macos/lokinet.entitlements.plist" \
|
||||
--deep --strict --timestamp --options=runtime "$file"
|
||||
|
||||
if [ "@CODESIGN@" != "ON" ]; then
|
||||
echo "Cannot codesign: this build was not configured with codesigning" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
signit() {
|
||||
target="$1"
|
||||
entitlements="$2"
|
||||
echo -e "\n\e[33;1mSigning ${target/*\/Lokinet.app/Lokinet.app}...\e[0m" >&2
|
||||
codesign \
|
||||
--verbose=4 \
|
||||
--force \
|
||||
-s "@CODESIGN_ID@" \
|
||||
--entitlements "$entitlements" \
|
||||
--strict \
|
||||
--timestamp \
|
||||
--options=runtime \
|
||||
"$target"
|
||||
}
|
||||
|
||||
gui_entitlements="@PROJECT_SOURCE_DIR@/gui/node_modules/app-builder-lib/templates/entitlements.mac.plist"
|
||||
ext_entitlements="@PROJECT_SOURCE_DIR@/contrib/macos/lokinet-extension.@LOKINET_ENTITLEMENTS_TYPE@.entitlements.plist"
|
||||
app_entitlements="@PROJECT_SOURCE_DIR@/contrib/macos/lokinet.@LOKINET_ENTITLEMENTS_TYPE@.entitlements.plist"
|
||||
|
||||
SIGN_TARGET="@PROJECT_BINARY_DIR@/Lokinet.app"
|
||||
|
||||
for ext in systemextension appex; do
|
||||
netext="$SIGN_TARGET/@lokinet_ext_dir@/org.lokinet.network-extension.$ext"
|
||||
if [ -e "$netext" ]; then
|
||||
signit "$netext" "$ext_entitlements"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "@BUILD_GUI@" == "ON" ]; then
|
||||
gui_app="$SIGN_TARGET"/Contents/Helpers/Lokinet-GUI.app
|
||||
gui_sign_targets=()
|
||||
for bundle in \
|
||||
"$gui_app"/Contents/Frameworks/*.framework \
|
||||
"$gui_app"/Contents/Frameworks/*.app
|
||||
do
|
||||
|
||||
if [ -d "$bundle/Libraries" ]; then
|
||||
gui_sign_targets+=("$bundle"/Libraries/*.dylib)
|
||||
fi
|
||||
if [ -d "$bundle/Helpers" ]; then
|
||||
gui_sign_targets+=("$bundle"/Helpers/*)
|
||||
fi
|
||||
if [ -d "$bundle/Resources" ]; then
|
||||
for f in "$bundle/Resources"/*; do
|
||||
if [[ -f "$f" && -x "$f" && "$(file -b "$f")" == Mach-O* ]]; then
|
||||
gui_sign_targets+=("$f")
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
gui_sign_targets+=("$bundle")
|
||||
done
|
||||
|
||||
gui_sign_targets+=("$gui_app")
|
||||
|
||||
for target in "${gui_sign_targets[@]}"; do
|
||||
signit "$target" "$gui_entitlements"
|
||||
done
|
||||
|
||||
signit "$SIGN_TARGET"/Contents/MacOS/Lokinet "$app_entitlements"
|
||||
fi
|
||||
|
||||
signit "$SIGN_TARGET" "$app_entitlements"
|
||||
|
@ -1,12 +0,0 @@
|
||||
diff --git a/tests/testutil.hpp b/tests/testutil.hpp
|
||||
index c6f5e4de..6a1c8bb8 100644
|
||||
--- a/tests/testutil.hpp
|
||||
+++ b/tests/testutil.hpp
|
||||
@@ -102,7 +102,6 @@ const uint8_t zmtp_ready_sub[27] = {
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <stdexcept>
|
||||
-#define close closesocket
|
||||
typedef int socket_size_t;
|
||||
inline const char *as_setsockopt_opt_t (const void *opt)
|
||||
{
|
@ -0,0 +1,14 @@
|
||||
diff --git a/tests/testutil.hpp b/tests/testutil.hpp
|
||||
index c6f5e4de78..09b9fa77e5 100644
|
||||
--- a/tests/testutil.hpp
|
||||
+++ b/tests/testutil.hpp
|
||||
@@ -41,6 +41,9 @@
|
||||
// For AF_INET and IPPROTO_TCP
|
||||
#if defined _WIN32
|
||||
#include "../src/windows.hpp"
|
||||
+#if defined(__MINGW32__)
|
||||
+#include <unistd.h>
|
||||
+#endif
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
@ -1,73 +1,123 @@
|
||||
Codesigning and notarization on macOS
|
||||
If you are reading this to try to build Lokinet for yourself for an Apple operating system and
|
||||
simultaneously care about open source, privacy, or freedom then you, my friend, are a walking
|
||||
contradiction: you are trying to get Lokinet to work on a platform that actively despises open
|
||||
source, privacy, and freedom. Even Windows is a better choice in all of these categories than
|
||||
Apple.
|
||||
|
||||
This is painful. Thankfully most of the pain is now in CMake and a python script.
|
||||
This directory contains the magical incantations and random voodoo symbols needed to coax an Apple
|
||||
build. There's no reason builds have to be this stupid, except that Apple wants to funnel everyone
|
||||
into the no-CI, no-help, undocumented, non-toy-apps-need-not-apply modern Apple culture.
|
||||
|
||||
To build, codesign, and notarized and installer package, CMake needs to be invoked with:
|
||||
This is disgusting.
|
||||
|
||||
cd build
|
||||
rm -rf * # optional but recommended
|
||||
cmake .. -DBUILD_PACKAGE=ON -DDOWNLOAD_SODIUM=ON -DMACOS_SIGN_APP=ABC123... -DMACOS_SIGN_PKG=DEF456...
|
||||
But it gets worse.
|
||||
|
||||
where the ABC123... key is a "Developer ID Installer" key and PKG key is a "Developer ID
|
||||
Application" key. You have to go through a bunch of pain, pay Apple money, and then read a bunch of
|
||||
poorly written documentation that doesn't help very much to create these and get them working. But once you have them
|
||||
set up in Keychain, you should be able to list your keys with:
|
||||
The following two files, in particular, are the very worst manifestations of this already toxic
|
||||
Apple cancer: they are required for proper permissions to run on macOS, are undocumented, and can
|
||||
only be regenerated through the entirely closed source Apple Developer backend, for which you have
|
||||
to pay money first to get a team account (a personal account will not work), and they lock the
|
||||
resulting binaries to only run on individually selected Apple computers selected at the time the
|
||||
profile is provisioned (with no ability to allow it to run anywhere).
|
||||
|
||||
security find-identity -v
|
||||
lokinet.dev.provisionprofile
|
||||
lokinet-extension.dev.provisionprofile
|
||||
|
||||
and you should see (at least) one "Developer ID Installer: ..." and one "Developer ID Application:
|
||||
...". You need both for reasons that only Apple knows. The former is used to sign the installer
|
||||
.pkg, and the latter is used to sign everything *inside* the .pkg, and you can't use the same key
|
||||
for both because Apple designed code signing by marketing committee rather than ask any actual
|
||||
competent software developers how code signing should work.
|
||||
This is actively hostile to open source development, but that is nothing new for Apple.
|
||||
|
||||
Either way, these two values can be specified either by hex value or description string that
|
||||
`security find-identity -v` spits out.
|
||||
There are also release provisioning profiles
|
||||
|
||||
You also need to set up the notarization parameters; these can either be specified directly on the
|
||||
cmake command line by adding:
|
||||
lokinet.release.provisionprofile
|
||||
lokinet-extension.release.provisionprofile
|
||||
|
||||
-DMACOS_NOTARIZE_ASC=XYZ123 -DMACOS_NOTARIZE_USER=me@example.com -DMACOS_NOTARIZE_PASS=@keychain:codesigning-password
|
||||
These ones allow distribution of the app, but only if notarized, and again require notarization plus
|
||||
signing by a (paid) Apple developer account.
|
||||
|
||||
or, more simply, by putting them inside a `~/.notarization.cmake` file that will be included if it
|
||||
exists (and the MACOS_SIGN_* variables are set) -- see below.
|
||||
In order to make things work, you'll have to replace these provisioning profiles with your own
|
||||
(after paying Apple for the privilege of developing on their platform, of course) and change all the
|
||||
team/application/bundle IDs to reference your own team, matching the provisioning profiles. The dev
|
||||
provisioning profiles must be a "macOS Development" provisioning profile, and must include the
|
||||
signing keys and the authorized devices on which you want to run it. (The profiles bundled in this
|
||||
repository contains the lokinet team's "Apple Development" keys associated with the Oxen project,
|
||||
and mac dev boxes. This is *useless* for anyone else).
|
||||
|
||||
These three values here are:
|
||||
For release builds, you still need a provisioning profile, but it must be a "Distribution: Developer
|
||||
ID" provisioning profile, and are tied to a (paid) Developer ID. The ones in the repository are
|
||||
attached to the Oxen Project Developer ID and are useless to anyone else.
|
||||
|
||||
MACOS_NOTARIZE_ASC:
|
||||
Once you have that in place, you need to build and sign the package using a certificate matching
|
||||
your provisioning profile before your Apple system will allow it to run. (That's right, your $2000
|
||||
box won't let you run programs you build from source on it unless you also subscribe to a $100/year
|
||||
Apple developer account).
|
||||
|
||||
Organization-specific unique value; this is printed inside (brackets) when you run: `security
|
||||
find-identity -v`:
|
||||
Okay, so now that you have paid Apple more money for the privilege of using your own computer,
|
||||
here's how you make a signed lokinet app:
|
||||
|
||||
1) 1C75DDBF884DEF3D5927C3F29BB7FC5ADAE2E1B3 "Apple Development: me@example.com (ABC123XYZ9)"
|
||||
1) Decide which type of build you are doing: a lokinet system extension, or an app extension. The
|
||||
former must be signed and notarized and will only work when placed in the /Applications folder,
|
||||
but will not work as a dev build and cannot be distributed outside the Mac App Store. The latter
|
||||
is usable as a dev build, but still requires a signature and Apple-provided provisioningprofile
|
||||
listing the limited number of devices on which it is allowed to run.
|
||||
|
||||
MACOS_NOTARIZE_USER:
|
||||
For system extension builds you want to add the -DMACOS_SYSTEM_EXTENSION=ON flag to cmake.
|
||||
|
||||
Your Apple Developer login.
|
||||
2) Figure out the certificate to use for signing and make sure you have it installed. For a
|
||||
distributable system extension build you need a "Developer ID Application" key and certificate,
|
||||
issued by your paid developer.apple.com account. For dev builds you need a "Apple Development"
|
||||
certificate.
|
||||
|
||||
MACOS_NOTARIZE_PASS:
|
||||
In most cases you don't need to specify these; the default cmake script will figure them out.
|
||||
(If it can't, e.g. because you have multiple of the right type installed, it will error with the
|
||||
keys it found).
|
||||
|
||||
This should be an app-specific password created for signing on the Apple Developer website. You
|
||||
*can* specify it directly, but it is much better to use the magic `@keychain:blah` value, where
|
||||
'blah' is a password name recorded in Keychain. To get that in place you run:
|
||||
To be explicit, use `security find-identity -v` to list your keys, then list the key identity
|
||||
with -DCODESIGN_ID=.....
|
||||
|
||||
export HISTFILE='' # for bash: you don't want to store this in your history
|
||||
xcrun altool --store-password-in-keychain-item "NOTARIZE_PASSWORD" -u "user" -p "password"
|
||||
3) If you are doing a system extension build you will need to provide notarization login information by adding:
|
||||
|
||||
where NOTARIZE_PASSWORD is just some name for the password (I called it 'blah' or
|
||||
'codesigning-password' above), and the "user" and "password" are replaced with your actual Apple
|
||||
Developer account device-specific login credentials.
|
||||
-DMACOS_NOTARIZE_ASC=XYZ123 -DMACOS_NOTARIZE_USER=me@example.com -DMACOS_NOTARIZE_PASS=@keychain:codesigning-password
|
||||
|
||||
Optionally, put these last three inside a `~/.notarization.cmake` file:
|
||||
a) The first value (XYZ123) needs to be the organization-specific unique value, and is printed in
|
||||
brackets in the certificate description. For example:
|
||||
|
||||
set(MACOS_NOTARIZE_USER "jagerman@jagerman.com")
|
||||
set(MACOS_NOTARIZE_PASS "@keychain:codesigning-password")
|
||||
set(MACOS_NOTARIZE_ASC "SUQ8J2PCT7")
|
||||
15095CD1E6AF441ABC69BDC52EE186A18200A49F "Developer ID Application: Some Developer (ABC123XYZ9)"
|
||||
|
||||
Then, finally, you can build the package from the build directory with:
|
||||
would require ABC123XYZ9 for this field.
|
||||
|
||||
make package -j4 # or whatever -j makes you happy
|
||||
make notarize
|
||||
b) The USER field is your Apple Developer login e-mail address.
|
||||
|
||||
The former builds and signs the package, the latter submits it for notarization. This can take a
|
||||
few minutes; the script polls Apple's server until it is finished passing or failing notarization.
|
||||
c) The PASS field is a keychain reference holding your "Application-Specific Password". To set
|
||||
up such a password for your account, consult Apple documentation. Once you have it, load it
|
||||
into your keychain via:
|
||||
|
||||
export HISTFILE='' # Don't want to store this in the shell history
|
||||
xcrun altool --store-password-in-keychain-item "codesigning-password" -u "user" -p "password"
|
||||
|
||||
You can change "codesigning-password" to whatever you want (just make sure it agrees with the
|
||||
-DMACOS_NOTARIZE_PASS option you build with). "user" and "password" should be your developer
|
||||
account device-specific login credentials provided by Apple.
|
||||
|
||||
To make your life easier, stash these settings into a `~/.notarization.cmake` file inside your
|
||||
home directory; if you have not specified them in the build, and this file exists, lokinet's
|
||||
cmake will load it:
|
||||
|
||||
set(MACOS_NOTARIZE_USER "me@example.com")
|
||||
set(MACOS_NOTARIZE_PASS "@keychain:codesigning-password")
|
||||
set(MACOS_NOTARIZE_ASC "ABC123XYZ9")
|
||||
|
||||
4) Build and sign the package; there is a script `contrib/mac.sh` that can help (extra cmake options
|
||||
you need can be appended to the end), or you can build yourself in a build directory. See the
|
||||
script for the other cmake options that are typically needed. Note that `-G Ninja` (as well as a
|
||||
working ninja builder) are required.
|
||||
|
||||
If you get an error `errSecInternalComponent` this is Apple's highly descriptive way of telling
|
||||
you that you need to unlock your keychain, which you can do by running `security unlock`.
|
||||
|
||||
If doing it yourself, `ninja sign` will build and then sign the app.
|
||||
|
||||
If you need to also notarize (e.g. for a system extension build) run `./notarize.py` from the
|
||||
build directory (or alternatively `ninja notarize`, but the former gives you status output while
|
||||
it runs).
|
||||
|
||||
5) Packaging the app: you want to use `-DBUILD_PACKAGE=ON` when configuring with cmake and then,
|
||||
once all signing and notarization is complete, run `cpack` which will give you a .dmg and a .zip
|
||||
containing the release.
|
||||
|
@ -0,0 +1 @@
|
||||
Subproject commit abcd94814e261ffd88104357e3946201d0d2c8e0
|
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace llarp::apple
|
||||
{
|
||||
/// Localhost port on macOS where we proxy DNS requests *through* the tunnel, because without
|
||||
/// calling into special snowflake Apple network APIs an extension's network connections all go
|
||||
/// around the tunnel, even when the tunnel is (supposedly) the default route.
|
||||
inline constexpr std::uint16_t dns_trampoline_port = 1053;
|
||||
|
||||
/// We query the above trampoline from unbound with this fixed source port (so that the trampoline
|
||||
/// is simplified by not having to track different ports for different requests).
|
||||
inline constexpr std::uint16_t dns_trampoline_source_port = 1054;
|
||||
} // namespace llarp::apple
|
Loading…
Reference in New Issue