mirror of https://github.com/oxen-io/lokinet
Merge branch 'dev' into debian/buster
commit
08b74d2647
@ -1,7 +0,0 @@
|
||||
function(add_log_tag target)
|
||||
get_target_property(TARGET_SRCS ${target} SOURCES)
|
||||
foreach(F ${TARGET_SRCS})
|
||||
get_filename_component(fpath "${F}" ABSOLUTE)
|
||||
set_property(SOURCE ${F} APPEND PROPERTY COMPILE_DEFINITIONS SOURCE_ROOT=\"${PROJECT_SOURCE_DIR}\")
|
||||
endforeach()
|
||||
endfunction()
|
@ -0,0 +1,6 @@
|
||||
set(default_build_gui OFF)
|
||||
if(APPLE OR WIN32)
|
||||
set(default_build_gui ON)
|
||||
endif()
|
||||
|
||||
option(BUILD_GUI "build electron gui from 'gui' submodule source" ${default_build_gui})
|
@ -0,0 +1,77 @@
|
||||
|
||||
set(default_gui_target pack)
|
||||
if(APPLE)
|
||||
set(default_gui_target macos:raw)
|
||||
elseif(WIN32)
|
||||
set(default_gui_target win32)
|
||||
set(GUI_EXE "" CACHE FILEPATH "path to an externally built lokinet gui.exe")
|
||||
endif()
|
||||
|
||||
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")
|
||||
# allow manually specifying yarn with -DYARN=
|
||||
if(NOT YARN)
|
||||
find_program(YARN NAMES yarnpkg yarn REQUIRED)
|
||||
endif()
|
||||
message(STATUS "Building lokinet-gui with yarn ${YARN}, target ${GUI_YARN_TARGET}")
|
||||
|
||||
|
||||
if(NOT WIN32)
|
||||
add_custom_target(lokinet-gui
|
||||
COMMAND ${YARN} install --frozen-lockfile &&
|
||||
${YARN} ${GUI_YARN_EXTRA_OPTS} ${GUI_YARN_TARGET}
|
||||
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/gui")
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
add_custom_target(assemble_gui ALL
|
||||
DEPENDS assemble lokinet-gui
|
||||
COMMAND mkdir "${lokinet_app}/Contents/Helpers"
|
||||
COMMAND cp -a "${PROJECT_SOURCE_DIR}/gui/release/mac/Lokinet-GUI.app" "${lokinet_app}/Contents/Helpers/"
|
||||
COMMAND mkdir -p "${lokinet_app}/Contents/Resources/en.lproj"
|
||||
COMMAND cp "${PROJECT_SOURCE_DIR}/contrib/macos/InfoPlist.strings" "${lokinet_app}/Contents/Resources/en.lproj/"
|
||||
COMMAND cp "${lokinet_app}/Contents/Resources/icon.icns" "${lokinet_app}/Contents/Helpers/Lokinet-GUI.app/Contents/Resources/icon.icns"
|
||||
COMMAND cp "${PROJECT_SOURCE_DIR}/contrib/macos/InfoPlist.strings" "${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}"
|
||||
"${lokinet_app}/Contents/Helpers/Lokinet-GUI.app/Contents/Info.plist"
|
||||
)
|
||||
elseif(WIN32)
|
||||
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/gui")
|
||||
option(GUI_ZIP_FILE "custom lokinet gui for windows from zip file" OFF)
|
||||
if(GUI_ZIP_FILE)
|
||||
message(STATUS "using custom lokinet gui from ${GUI_ZIP_FILE}")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf ${GUI_ZIP_FILE}
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
|
||||
add_custom_target("${PROJECT_BINARY_DIR}/gui/lokinet-gui.exe" COMMAND "true")
|
||||
elseif(GUI_EXE)
|
||||
message(STATUS "using custom lokinet gui executable: ${GUI_EXE}")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${GUI_EXE}" "${PROJECT_BINARY_DIR}/gui/lokinet-gui.exe")
|
||||
add_custom_target("${PROJECT_BINARY_DIR}/gui/lokinet-gui.exe" COMMAND "true")
|
||||
else()
|
||||
add_custom_command(OUTPUT "${PROJECT_BINARY_DIR}/gui/lokinet-gui.exe"
|
||||
COMMAND ${YARN} install --frozen-lockfile &&
|
||||
USE_SYSTEM_7ZA=true DISPLAY= WINEDEBUG=-all WINEPREFIX="${PROJECT_BINARY_DIR}/wineprefix" ${YARN} ${GUI_YARN_EXTRA_OPTS} ${GUI_YARN_TARGET}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${PROJECT_SOURCE_DIR}/gui/release/Lokinet-GUI_portable.exe"
|
||||
"${PROJECT_BINARY_DIR}/gui/lokinet-gui.exe"
|
||||
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/gui")
|
||||
endif()
|
||||
add_custom_target(assemble_gui ALL COMMAND "true" DEPENDS "${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 gui")
|
||||
endif()
|
||||
|
||||
if(NOT TARGET assemble_gui)
|
||||
add_custom_target(assemble_gui COMMAND "true")
|
||||
endif()
|
@ -0,0 +1,214 @@
|
||||
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")
|
||||
set(CODESIGN_EXT_PROFILE "${PROJECT_SOURCE_DIR}/contrib/macos/lokinet-extension.${default_profile_type}.provisionprofile" CACHE FILEPATH
|
||||
"Path to a .provisionprofile to use for the lokinet extension")
|
||||
|
||||
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()
|
||||
|
||||
|
||||
foreach(prof IN ITEMS CODESIGN_PROFILE CODESIGN_EXT_PROFILE)
|
||||
if(NOT ${prof})
|
||||
message(WARNING "Missing a ${prof} 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")
|
||||
elseif(NOT EXISTS "${${prof}}")
|
||||
message(FATAL_ERROR "Provisioning profile ${${prof}} does not exist; fix your -D${prof} path")
|
||||
endif()
|
||||
endforeach()
|
||||
message(STATUS "Using ${CODESIGN_PROFILE} app provisioning profile")
|
||||
message(STATUS "Using ${CODESIGN_EXT_PROFILE} extension provisioning profile")
|
||||
|
||||
|
||||
|
||||
set(lokinet_installer "${PROJECT_BINARY_DIR}/Lokinet ${PROJECT_VERSION}")
|
||||
if(NOT CODESIGN)
|
||||
set(lokinet_installer "${lokinet_installer}-UNSIGNED")
|
||||
endif()
|
||||
set(lokinet_app "${lokinet_installer}/Lokinet.app")
|
||||
|
||||
|
||||
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()
|
||||
|
||||
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-mac.svg ${PROJECT_SOURCE_DIR}/contrib/macos/mk-icns.sh)
|
||||
add_custom_target(icon DEPENDS "${mac_icon}")
|
||||
|
||||
if(BUILD_PACKAGE)
|
||||
add_executable(seticon "${PROJECT_SOURCE_DIR}/contrib/macos/seticon.swift")
|
||||
add_custom_command(OUTPUT "${lokinet_installer}.dmg"
|
||||
DEPENDS notarize seticon
|
||||
COMMAND create-dmg
|
||||
--volname "Lokinet ${PROJECT_VERSION}"
|
||||
--volicon lokinet.icns
|
||||
#--background ... FIXME
|
||||
--text-size 16
|
||||
--icon-size 128
|
||||
--window-size 500 300
|
||||
--icon Lokinet.app 100 100
|
||||
--hide-extension Lokinet.app
|
||||
--app-drop-link 350 100
|
||||
--eula "${PROJECT_SOURCE_DIR}/LICENSE"
|
||||
--no-internet-enable
|
||||
"${lokinet_installer}.dmg"
|
||||
"${lokinet_installer}"
|
||||
COMMAND ./seticon lokinet.icns "${lokinet_installer}.dmg"
|
||||
)
|
||||
add_custom_target(package DEPENDS "${lokinet_installer}.dmg")
|
||||
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
|
||||
)
|
||||
|
||||
|
||||
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 "${lokinet_app}"
|
||||
COMMAND mkdir -p "${lokinet_installer}"
|
||||
COMMAND cp -a $<TARGET_BUNDLE_DIR:lokinet> "${lokinet_app}"
|
||||
COMMAND mkdir -p "${lokinet_app}/${lokinet_ext_dir}"
|
||||
COMMAND cp -a $<TARGET_BUNDLE_DIR:lokinet-extension> "${lokinet_app}/${lokinet_ext_dir}/"
|
||||
COMMAND mkdir -p "${lokinet_app}/Contents/Resources"
|
||||
COMMAND cp -a "${mac_icon}" "${lokinet_app}/Contents/Resources/icon.icns"
|
||||
)
|
||||
|
||||
if(BUILD_GUI)
|
||||
add_dependencies(sign assemble_gui)
|
||||
else()
|
||||
add_dependencies(sign assemble)
|
||||
endif()
|
||||
endfunction()
|
@ -1,18 +0,0 @@
|
||||
set(WITH_STATIC OFF)
|
||||
set(WITH_SHARED ON)
|
||||
if("${SHADOW_ROOT}" STREQUAL "")
|
||||
set(SHADOW_ROOT "$ENV{HOME}/.shadow")
|
||||
endif("${SHADOW_ROOT}" STREQUAL "")
|
||||
if(EXISTS "${SHADOW_ROOT}")
|
||||
message(STATUS "SHADOW_ROOT = ${SHADOW_ROOT}")
|
||||
else()
|
||||
message(FATAL_ERROR "SHADOW_ROOT path does not exist: '${SHADOW_ROOT}'")
|
||||
endif(EXISTS "${SHADOW_ROOT}")
|
||||
|
||||
set(CMAKE_MODULE_PATH "${SHADOW_ROOT}/share/cmake/Modules")
|
||||
include_directories(${CMAKE_MODULE_PATH})
|
||||
include(ShadowTools)
|
||||
add_compile_options(-fno-inline -fno-strict-aliasing )
|
||||
add_definitions(-DTESTNET=1)
|
||||
add_definitions(-DLOKINET_SHADOW)
|
||||
include_directories(${SHADOW_ROOT}/include)
|
@ -1,32 +1,52 @@
|
||||
if(NOT WIN32)
|
||||
return()
|
||||
endif()
|
||||
if (NOT STATIC_LINK)
|
||||
message(FATAL_ERROR "windows requires static builds (thanks balmer)")
|
||||
endif()
|
||||
|
||||
enable_language(RC)
|
||||
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
|
||||
if(NOT MSVC_VERSION)
|
||||
add_compile_options($<$<COMPILE_LANGUAGE:C>:-Wno-bad-function-cast>)
|
||||
add_compile_options($<$<COMPILE_LANGUAGE:C>:-Wno-cast-function-type>)
|
||||
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fpermissive>)
|
||||
# unlike unix where you get a *single* compiler ID string in .comment
|
||||
# GNU ld sees fit to merge *all* the .ident sections in object files
|
||||
# to .r[o]data section one after the other!
|
||||
add_compile_options(-fno-ident -Wa,-mbig-obj)
|
||||
link_libraries( -lws2_32 -lshlwapi -ldbghelp -luser32 -liphlpapi -lpsapi -luserenv)
|
||||
# the minimum windows version, set to 6 rn because supporting older windows is hell
|
||||
set(_winver 0x0600)
|
||||
add_definitions(-DWINVER=${_winver} -D_WIN32_WINNT=${_winver})
|
||||
endif()
|
||||
option(WITH_WINDOWS_32 "build 32 bit windows" OFF)
|
||||
|
||||
# unlike unix where you get a *single* compiler ID string in .comment
|
||||
# GNU ld sees fit to merge *all* the .ident sections in object files
|
||||
# to .r[o]data section one after the other!
|
||||
add_compile_options(-fno-ident -Wa,-mbig-obj)
|
||||
# the minimum windows version, set to 6 rn because supporting older windows is hell
|
||||
set(_winver 0x0600)
|
||||
add_definitions(-D_WIN32_WINNT=${_winver})
|
||||
|
||||
if(EMBEDDED_CFG)
|
||||
link_libatomic()
|
||||
endif()
|
||||
|
||||
add_definitions(-DWIN32_LEAN_AND_MEAN -DWIN32)
|
||||
set(WINTUN_VERSION 0.14.1 CACHE STRING "wintun version")
|
||||
set(WINTUN_MIRROR https://www.wintun.net/builds
|
||||
CACHE STRING "wintun mirror(s)")
|
||||
set(WINTUN_SOURCE wintun-${WINTUN_VERSION}.zip)
|
||||
set(WINTUN_HASH SHA256=07c256185d6ee3652e09fa55c0b673e2624b565e02c4b9091c79ca7d2f24ef51
|
||||
CACHE STRING "wintun source hash")
|
||||
|
||||
if (NOT STATIC_LINK AND NOT MSVC)
|
||||
message("must ship compiler runtime libraries with this build: libwinpthread-1.dll, libgcc_s_dw2-1.dll, and libstdc++-6.dll")
|
||||
message("for release builds, turn on STATIC_LINK in cmake options")
|
||||
endif()
|
||||
set(WINDIVERT_VERSION 2.2.0-A CACHE STRING "windivert version")
|
||||
set(WINDIVERT_MIRROR https://reqrypt.org/download
|
||||
CACHE STRING "windivert mirror(s)")
|
||||
set(WINDIVERT_SOURCE WinDivert-${WINDIVERT_VERSION}.zip)
|
||||
set(WINDIVERT_HASH SHA256=2a7630aac0914746fbc565ac862fa096e3e54233883ac52d17c83107496b7a7f
|
||||
CACHE STRING "windivert source hash")
|
||||
|
||||
set(WINTUN_URL ${WINTUN_MIRROR}/${WINTUN_SOURCE}
|
||||
CACHE STRING "wintun download url")
|
||||
set(WINDIVERT_URL ${WINDIVERT_MIRROR}/${WINDIVERT_SOURCE}
|
||||
CACHE STRING "windivert download url")
|
||||
|
||||
message(STATUS "Downloading wintun from ${WINTUN_URL}")
|
||||
file(DOWNLOAD ${WINTUN_URL} ${CMAKE_BINARY_DIR}/wintun.zip EXPECTED_HASH ${WINTUN_HASH})
|
||||
message(STATUS "Downloading windivert from ${WINDIVERT_URL}")
|
||||
file(DOWNLOAD ${WINDIVERT_URL} ${CMAKE_BINARY_DIR}/windivert.zip EXPECTED_HASH ${WINDIVERT_HASH})
|
||||
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E tar x ${CMAKE_BINARY_DIR}/wintun.zip
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E tar x ${CMAKE_BINARY_DIR}/windivert.zip
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
@ -0,0 +1,2 @@
|
||||
[logging]
|
||||
level=debug
|
@ -0,0 +1,5 @@
|
||||
#
|
||||
# "suggested" default exit node config
|
||||
#
|
||||
[network]
|
||||
exit-node=exit.loki
|
@ -0,0 +1,5 @@
|
||||
#
|
||||
# persist .loki address in a private key file in the data dir
|
||||
#
|
||||
[network]
|
||||
keyfile=lokinet-addr.privkey
|
@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# .loki secret key generator script
|
||||
# makes keyfile contents
|
||||
#
|
||||
# usage: python3 keygen.py out.private
|
||||
# python3 keygen.py > /some/where/over/the/rainbow
|
||||
#
|
||||
from nacl.bindings import crypto_sign_keypair
|
||||
import sys
|
||||
|
||||
out = sys.stdout
|
||||
|
||||
close_out = lambda : None
|
||||
args = sys.argv[1:]
|
||||
|
||||
if args and args[0] != '-':
|
||||
out = open(args[0], 'wb')
|
||||
close_out = out.close
|
||||
|
||||
pk, sk = crypto_sign_keypair()
|
||||
out.write(b'64:')
|
||||
out.write(sk)
|
||||
out.flush()
|
||||
close_out()
|
||||
|
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- our size/viewbox is positioned such that 0,0 is the center of the image (to simplify scaling and rotation). -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="-512px" y="-512px"
|
||||
viewBox="-512 -512 1024 1024" style="enable-background:new -512 -512 1024 1024;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.bg{fill:#FFFFFF;}
|
||||
</style>
|
||||
|
||||
<!--
|
||||
Draw the background shape in a 2x2 box (from -1 to 1 in each dimension), then scale it up
|
||||
(but not all the way to 512, because we want some padding around the outside.
|
||||
-->
|
||||
<g transform="scale(415)">
|
||||
<path class="bg" d="
|
||||
M 0.5 1
|
||||
H -0.5
|
||||
C -0.81,1 -1,0.81 -1,0.5
|
||||
V -0.5
|
||||
C -1,-0.81 -0.81,-1 -0.5,-1
|
||||
H 0.5
|
||||
C 0.81,-1 1,-0.81 1,-0.5
|
||||
V 0.5
|
||||
C 1,0.81 0.81,1 0.5,1
|
||||
z
|
||||
"/>
|
||||
</g>
|
||||
|
||||
<g id="shape0">
|
||||
<!--
|
||||
Start with a simple 3x2 shape, where each unit we draw corresponds to 1 block edge length in the
|
||||
final diagram, and shift it so that 2.5x2.5 becomes the new origin (around which we will rotate).
|
||||
Then we rotate and scale it to the desired size.
|
||||
|
||||
We can then copy that at 90, 180, 270 degree rotations to complete the logo.
|
||||
-->
|
||||
<g transform="rotate(45) scale(85) translate(-2.5, -2.5)">
|
||||
<polygon points="0,0 2,0 2,1 1,1 1,2 0,2"/>
|
||||
<rect x="1" y="2" width="1" height="1"/>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<use xlink:href="#shape0" transform="rotate(90)"/>
|
||||
<use xlink:href="#shape0" transform="rotate(180)"/>
|
||||
<use xlink:href="#shape0" transform="rotate(270)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
@ -1,21 +1,34 @@
|
||||
<?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 189.4 189.4" style="enable-background:new 0 0 189.4 189.4;" xml:space="preserve">
|
||||
<!-- our size/viewbox is positioned such that 0,0 is the center of the image (to simplify scaling and rotation). -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="-512px" y="-512px"
|
||||
viewBox="-512 -512 1024 1024" style="enable-background:new -512 -512 1024 1024;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
.bg{fill:#FFFFFF;}
|
||||
</style>
|
||||
<g>
|
||||
<polygon class="st0" points="113.6,132.6 94.7,151.5 75.8,132.6 56.8,151.5 94.7,189.4 132.6,151.5 "/>
|
||||
<polygon class="st0" points="132.6,113.6 151.5,94.7 132.6,75.8 151.5,56.8 189.4,94.7 151.5,132.6 "/>
|
||||
<polygon class="st0" points="56.8,75.8 37.9,94.7 56.8,113.6 37.9,132.6 0,94.7 37.9,56.8 "/>
|
||||
<polygon class="st0" points="75.8,56.8 94.7,37.9 113.6,56.8 132.6,37.9 94.7,0 56.8,37.9 "/>
|
||||
|
||||
<rect x="100.2" y="100.2" transform="matrix(0.7071 0.7071 -0.7071 0.7071 113.6329 -47.0683)" class="st0" width="26.8" height="26.8"/>
|
||||
|
||||
<rect x="62.4" y="62.4" transform="matrix(0.7071 0.7071 -0.7071 0.7071 75.7552 -31.3789)" class="st0" width="26.8" height="26.8"/>
|
||||
|
||||
<rect x="100.2" y="62.4" transform="matrix(0.7071 0.7071 -0.7071 0.7071 86.8493 -58.1624)" class="st0" width="26.8" height="26.8"/>
|
||||
|
||||
<rect x="62.4" y="100.2" transform="matrix(0.7071 0.7071 -0.7071 0.7071 102.5388 -20.2848)" class="st0" width="26.8" height="26.8"/>
|
||||
|
||||
<!--
|
||||
Draw the background shape in a 2x2 box (from -1 to 1 in each dimension), then scale it up
|
||||
(but not all the way to 512, because we want some padding around the outside.
|
||||
-->
|
||||
<g transform="scale(512)">
|
||||
<circle r="1" class="bg"/>
|
||||
</g>
|
||||
|
||||
<g id="shape0">
|
||||
<!--
|
||||
Start with a simple 3x2 shape, where each unit we draw corresponds to 1 block edge length in the
|
||||
final diagram, and shift it so that 2.5x2.5 becomes the new origin (around which we will rotate).
|
||||
Then we rotate and scale it to the desired size.
|
||||
|
||||
We can then copy that at 90, 180, 270 degree rotations to complete the logo.
|
||||
-->
|
||||
<g transform="rotate(45) scale(105) translate(-2.5, -2.5)">
|
||||
<polygon points="0,0 2,0 2,1 1,1 1,2 0,2"/>
|
||||
<rect x="1" y="2" width="1" height="1"/>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<use xlink:href="#shape0" transform="rotate(90)"/>
|
||||
<use xlink:href="#shape0" transform="rotate(180)"/>
|
||||
<use xlink:href="#shape0" transform="rotate(270)"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.4 KiB |
@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
if ! [ -f LICENSE ] || ! [ -d llarp ]; then
|
||||
echo "You need to run this as ./contrib/mac.sh from the top-level lokinet project directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p build-mac
|
||||
cd build-mac
|
||||
cmake \
|
||||
-G Ninja \
|
||||
-DBUILD_STATIC_DEPS=ON \
|
||||
-DBUILD_LIBLOKINET=OFF \
|
||||
-DWITH_TESTS=OFF \
|
||||
-DWITH_BOOTSTRAP=OFF \
|
||||
-DNATIVE_BUILD=OFF \
|
||||
-DWITH_LTO=ON \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DMACOS_SYSTEM_EXTENSION=ON \
|
||||
-DCODESIGN=ON \
|
||||
-DBUILD_PACKAGE=ON \
|
||||
"$@" \
|
||||
..
|
||||
|
||||
echo "cmake build configured in build-mac"
|
@ -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,45 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
scutil_query()
|
||||
{
|
||||
key=$1
|
||||
|
||||
scutil<<EOT
|
||||
open
|
||||
get $key
|
||||
d.show
|
||||
close
|
||||
EOT
|
||||
}
|
||||
|
||||
SERVICE_GUID=`scutil_query State:/Network/Global/IPv4 \
|
||||
| grep "PrimaryService" \
|
||||
| awk '{print $3}'`
|
||||
|
||||
SERVICE_NAME=`scutil_query Setup:/Network/Service/$SERVICE_GUID \
|
||||
| grep "UserDefinedName" \
|
||||
| awk -F': ' '{print $2}'`
|
||||
|
||||
OLD_SERVERS="$(networksetup -getdnsservers "$SERVICE_NAME" \
|
||||
| tr '\n' ' ' \
|
||||
| sed 's/ $//')"
|
||||
|
||||
# <3 Apple
|
||||
#
|
||||
# if there were no explicit DNS servers, this will return:
|
||||
# "There aren't any DNS Servers set on Ethernet."
|
||||
# This might be internationalized, so we'll suffice it to see if there's a space
|
||||
pattern=" |'"
|
||||
if [[ $OLD_SERVERS =~ $pattern ]]
|
||||
then
|
||||
# and when there aren't any explicit servers set, we want to pass the literal
|
||||
# string "empty"
|
||||
OLD_SERVERS="empty"
|
||||
fi
|
||||
|
||||
networksetup -setdnsservers "$SERVICE_NAME" 127.0.0.1
|
||||
|
||||
trap "networksetup -setdnsservers \"$SERVICE_NAME\" $OLD_SERVERS" INT TERM EXIT
|
||||
|
||||
/opt/lokinet/bin/lokinet /var/lib/lokinet/lokinet.ini
|
||||
|
@ -1,53 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -x
|
||||
test `whoami` == root || exit 1
|
||||
|
||||
# this is for dns tomfoolery
|
||||
scutil_query()
|
||||
{
|
||||
key=$1
|
||||
|
||||
scutil<<EOT
|
||||
open
|
||||
get $key
|
||||
d.show
|
||||
close
|
||||
EOT
|
||||
}
|
||||
|
||||
# get guid for service
|
||||
SERVICE_GUID=`scutil_query State:/Network/Global/IPv4 \
|
||||
| grep "PrimaryService" \
|
||||
| awk '{print $3}'`
|
||||
|
||||
# get name of network service
|
||||
SERVICE_NAME=`scutil_query Setup:/Network/Service/$SERVICE_GUID \
|
||||
| grep "UserDefinedName" \
|
||||
| awk -F': ' '{print $2}'`
|
||||
|
||||
# tell dns to be "empty" so that it's reset
|
||||
networksetup -setdnsservers "$SERVICE_NAME" empty
|
||||
|
||||
# Prevent restarting on exit
|
||||
touch /var/lib/lokinet/suspend-launchd-service
|
||||
|
||||
# shut off lokinet gracefully
|
||||
pgrep lokinet$ && /opt/lokinet/bin/lokinet-vpn --kill
|
||||
|
||||
# kill the gui and such
|
||||
killall LokinetGUI
|
||||
killall lokinet
|
||||
# if the launch daemon is there kill it
|
||||
/bin/launchctl stop network.loki.lokinet.daemon
|
||||
/bin/launchctl unload /Library/LaunchDaemons/network.loki.lokinet.daemon.plist
|
||||
|
||||
# kill it and make sure it's dead
|
||||
killall -9 lokinet
|
||||
|
||||
rm -rf /Library/LaunchDaemons/network.loki.lokinet.daemon.plist
|
||||
rm -rf /Applications/Lokinet/
|
||||
rm -rf /Applications/LokinetGUI.app
|
||||
rm -rf /var/lib/lokinet
|
||||
rm -rf /usr/local/lokinet/
|
||||
rm -rf /opt/lokinet
|
||||
rm -f /etc/newsyslog.d/lokinet.conf
|
@ -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,38 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
PERMS_OWNER=root
|
||||
PERMS_GROUP=admin
|
||||
CHOWN=$PERMS_OWNER:$PERMS_GROUP
|
||||
|
||||
# set up lokinet data dir
|
||||
[ -e /var/lib/lokinet/ ] || mkdir /var/lib/lokinet
|
||||
chown $CHOWN /var/lib/lokinet
|
||||
chmod g+w /var/lib/lokinet
|
||||
|
||||
# mv files copied into $INSTALL_PREFIX/extra/ to their proper locations
|
||||
mv /opt/lokinet/extra/lokinet_macos_daemon_script.sh /var/lib/lokinet
|
||||
chown $CHOWN /var/lib/lokinet/lokinet_macos_daemon_script.sh
|
||||
chmod 770 /var/lib/lokinet/lokinet_macos_daemon_script.sh
|
||||
|
||||
mv /opt/lokinet/extra/network.loki.lokinet.daemon.plist /Library/LaunchDaemons/
|
||||
chown $CHOWN /Library/LaunchDaemons/network.loki.lokinet.daemon.plist
|
||||
chmod 640 /Library/LaunchDaemons/network.loki.lokinet.daemon.plist
|
||||
|
||||
mv /opt/lokinet/extra/lokinet-newsyslog.conf /etc/newsyslog.d/lokinet.conf
|
||||
chown $CHOWN /etc/newsyslog.d/lokinet.conf
|
||||
chmod 640 /etc/newsyslog.d/lokinet.conf
|
||||
|
||||
# clean up by removing 'extra/' (so long as it's empty)
|
||||
rmdir /opt/lokinet/extra/
|
||||
|
||||
# bootstrap
|
||||
/opt/lokinet/bin/lokinet-bootstrap mainnet /var/lib/lokinet/bootstrap.signed
|
||||
chown $CHOWN /var/lib/lokinet/bootstrap.signed
|
||||
|
||||
# generate configs
|
||||
/opt/lokinet/bin/lokinet -g /var/lib/lokinet/lokinet.ini
|
||||
chown $CHOWN /var/lib/lokinet/lokinet.ini
|
||||
|
||||
# register with launchd and start
|
||||
launchctl load /Library/LaunchDaemons/network.loki.lokinet.daemon.plist
|
||||
launchctl start network.loki.lokinet.daemon
|
@ -1,46 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
|
||||
# this is for dns tomfoolery
|
||||
scutil_query()
|
||||
{
|
||||
key=$1
|
||||
|
||||
scutil<<EOT
|
||||
open
|
||||
get $key
|
||||
d.show
|
||||
close
|
||||
EOT
|
||||
}
|
||||
|
||||
# get guid for service
|
||||
SERVICE_GUID=`scutil_query State:/Network/Global/IPv4 \
|
||||
| grep "PrimaryService" \
|
||||
| awk '{print $3}'`
|
||||
|
||||
# get name of network service
|
||||
SERVICE_NAME=`scutil_query Setup:/Network/Service/$SERVICE_GUID \
|
||||
| grep "UserDefinedName" \
|
||||
| awk -F': ' '{print $2}'`
|
||||
|
||||
# tell dns to be "empty" so that it's reset
|
||||
networksetup -setdnsservers "$SERVICE_NAME" empty
|
||||
# suspend existing lokinet if it's there
|
||||
[ -e /var/lib/lokinet ] && touch /var/lib/lokinet/suspend-launchd-service
|
||||
# kill it
|
||||
killall lokinet || true
|
||||
# wait a sec
|
||||
sleep 1
|
||||
# make sure it's fucking dead
|
||||
killall -9 lokinet || true
|
||||
|
||||
# check for prexisting lokinet and kill it if it's there
|
||||
[ -e /Library/LaunchDaemons/network.loki.lokinet.daemon.plist ] && (
|
||||
launchctl stop network.loki.lokinet.daemon ;
|
||||
launchctl unload /Library/LaunchDaemons/network.loki.lokinet.daemon.plist ;
|
||||
rm -rf /Library/LaunchDaemons/network.loki.lokinet.daemon.plist
|
||||
)
|
||||
|
||||
# clear out the install dir beforehand
|
||||
rm -rf /opt/lokinet
|
@ -0,0 +1,26 @@
|
||||
import Foundation
|
||||
import AppKit
|
||||
|
||||
// Apple deprecated their command line tools to set images on things and replaced them with a
|
||||
// barely-documented swift function. Yay!
|
||||
|
||||
// Usage: ./seticon /path/to/my.icns /path/to/some.dmg
|
||||
|
||||
let args = CommandLine.arguments
|
||||
|
||||
if args.count != 3 {
|
||||
print("Error: usage: ./seticon /path/to/my.icns /path/to/some.dmg")
|
||||
exit(1)
|
||||
}
|
||||
|
||||
var icns = args[1]
|
||||
var dmg = args[2]
|
||||
|
||||
var img = NSImage(byReferencingFile: icns)!
|
||||
|
||||
if NSWorkspace.shared.setIcon(img, forFile: dmg) {
|
||||
print("Set \(dmg) icon to \(icns) [\(img.size)]")
|
||||
} else {
|
||||
print("Setting icon failed, don't know why")
|
||||
exit(2)
|
||||
}
|
@ -1,10 +1,74 @@
|
||||
#!/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 @PROJECT_VERSION@/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"
|
||||
|
||||
touch "@PROJECT_BINARY_DIR@"/macos-signed.stamp
|
||||
|
@ -1,85 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.10) # bionic's cmake version
|
||||
|
||||
# Has to be set before `project()`, and ignored on non-macos:
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.12 CACHE STRING "macOS deployment target (Apple clang only)")
|
||||
|
||||
find_program(CCACHE_PROGRAM ccache)
|
||||
if(CCACHE_PROGRAM)
|
||||
foreach(lang C CXX)
|
||||
if(NOT DEFINED CMAKE_${lang}_COMPILER_LAUNCHER AND NOT CMAKE_${lang}_COMPILER MATCHES ".*/ccache")
|
||||
message(STATUS "Enabling ccache for ${lang}")
|
||||
set(CMAKE_${lang}_COMPILER_LAUNCHER ${CCACHE_PROGRAM} CACHE STRING "")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
set(PROJECT_NAME lokinet-uninstaller)
|
||||
project(${PROJECT_NAME}
|
||||
VERSION 0.0.1
|
||||
DESCRIPTION "lokinet uninstaller for macos"
|
||||
LANGUAGES CXX)
|
||||
|
||||
add_executable(${PROJECT_NAME}
|
||||
main.cpp)
|
||||
|
||||
find_package(Qt5 COMPONENTS Widgets REQUIRED)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
"-framework Security"
|
||||
Qt5::Core Qt5::Widgets)
|
||||
|
||||
set_target_properties(${PROJECT_NAME}
|
||||
PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
CXX_EXTENSIONS OFF
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
)
|
||||
|
||||
|
||||
set(MACOS_SIGN ""
|
||||
CACHE STRING "enable codesigning -- use a 'Apple Distribution' key (or key description) from `security find-identity -v`")
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lokinet-uninstall.icns
|
||||
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/mk-icns.sh ${CMAKE_CURRENT_SOURCE_DIR}/icon.svg ${CMAKE_CURRENT_BINARY_DIR}/lokinet-uninstall.icns
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/icon.svg ${CMAKE_CURRENT_SOURCE_DIR}/mk-icns.sh)
|
||||
|
||||
target_sources(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/lokinet-uninstall.icns)
|
||||
|
||||
set_target_properties(${PROJECT_NAME}
|
||||
PROPERTIES
|
||||
MACOSX_BUNDLE TRUE
|
||||
OUTPUT_NAME UninstallLokinet
|
||||
RESOURCE "${CMAKE_CURRENT_BINARY_DIR}/lokinet-uninstall.icns")
|
||||
|
||||
set(MACOSX_BUNDLE_BUNDLE_NAME UninstallLokinet)
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER org.lokinet.lokinet-uninstaller)
|
||||
set(MACOSX_BUNDLE_INFO_STRING "Lokinet uninstaller")
|
||||
set(MACOSX_BUNDLE_ICON_FILE lokinet-uninstall.icns)
|
||||
set(MACOSX_BUNDLE_LONG_VERSION_STRING ${PROJECT_VERSION})
|
||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION})
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION})
|
||||
set(MACOSX_BUNDLE_COPYRIGHT "© 2020, The Loki Project")
|
||||
|
||||
get_target_property(uic_location Qt5::uic IMPORTED_LOCATION)
|
||||
get_filename_component(qt_dir ${uic_location} DIRECTORY)
|
||||
|
||||
if(MACOS_SIGN)
|
||||
add_custom_command(TARGET ${PROJECT_NAME}
|
||||
POST_BUILD
|
||||
COMMAND echo "Running qt magic macos deploy script"
|
||||
COMMAND "${qt_dir}/macdeployqt" UninstallLokinet.app -always-overwrite
|
||||
COMMAND echo "Signing app bundle and everything inside it"
|
||||
COMMAND codesign -s "${MACOS_SIGN}" --deep --strict --options runtime --force -vvv UninstallLokinet.app
|
||||
)
|
||||
else()
|
||||
add_custom_command(TARGET ${PROJECT_NAME}
|
||||
POST_BUILD
|
||||
COMMAND echo "Running qt magic macos deploy script"
|
||||
COMMAND "${qt_dir}/macdeployqt" UninstallLokinet.app -always-overwrite
|
||||
)
|
||||
endif()
|
||||
|
||||
install(TARGETS lokinet-uninstaller
|
||||
RUNTIME DESTINATION bin
|
||||
BUNDLE DESTINATION .
|
||||
RESOURCE DESTINATION .)
|
@ -1,26 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg data-name="Layer 1" version="1.1" viewBox="0 0 1e3 1e3" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title>lokinet icon</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs>
|
||||
<style type="text/css">.cls-1{fill:#fff;}.cls-2{fill:#6cbe45;}.cls-3{fill:none;stroke:#fff;stroke-linecap:round;stroke-miterlimit:10;stroke-width:9px;}.cls-4{fill:#1c1c1c;}</style>
|
||||
</defs>
|
||||
<title>lokinet icon</title>
|
||||
<circle class="cls-1" cx="500" cy="500" r="500"/>
|
||||
<path class="cls-2" transform="translate(.02 .11)" d="M502.6,560.44l8,7.34,14.5,13.09c.74.67,1.42,1.38,2.09,2.09L541,595.54a20.87,20.87,0,0,1,0,31l-16.8,15.2a38.3,38.3,0,0,0,4-3.08l94.71-85.73-55.92-50.64Z"/>
|
||||
<path class="cls-2" transform="translate(.02 .11)" d="m754.35 415.61v-0.52a69.39 69.39 0 0 0-23.13-50.47l-187.92-167.57a20.88 20.88 0 0 1-3.77 26.39l-14.07 12.73c-0.09 0.08-0.16 0.17-0.25 0.25l-25.1 22.71 168.94 150.65-46.22 41.83 116.27 105.29a46.54 46.54 0 0 1 15.28 34.54c0 1.28-0.1 2.55-0.21 3.82a38.26 38.26 0 0 0 0.23-4v-174.88c0-0.26-0.04-0.52-0.05-0.77z"/>
|
||||
<path class="cls-2" transform="translate(.02 .11)" d="m500 441.68-38.63-35a20.88 20.88 0 0 1 0-31l10.49-9.49 0.35-0.43a37.93 37.93 0 0 1 6.07-5.38 39 39 0 0 0-3.46 2.75l-95.23 86.2 56 50.57z"/>
|
||||
<path class="cls-2" transform="translate(.02 .11)" d="m460.61 776.35 11.83-10.7a32.29 32.29 0 0 1 2.34-2.34l25-22.59-166.32-148.34 46.15-41.77-118.72-107.23a46.58 46.58 0 0 1-15.31-34.47c0-1.48 0.09-3 0.23-4.43a36.09 36.09 0 0 0-0.25 4.18v174.85a69.42 69.42 0 0 0 23.19 51.75l188.46 168.07a20.86 20.86 0 0 1 3.4-26.98z"/>
|
||||
<path class="cls-3" transform="translate(.02 .11)" d="m525 422.75"/>
|
||||
<path class="cls-4" transform="translate(.02 .11)" d="M754.38,591.44A46.54,46.54,0,0,0,739.1,556.9L525.19,363.21c-.24-.22-.51-.41-.76-.62l-10.26-9.29a20.86,20.86,0,0,0-28,0l-7.92,7.16a37.93,37.93,0,0,0-6.07,5.38l-.35.43-10.49,9.49a20.88,20.88,0,0,0,0,31l38.83,35.15,0,0,165.1,149.5-190.51,172a32.29,32.29,0,0,0-2.34,2.34l-11.83,10.7a20.87,20.87,0,0,0,0,30.95l24.82,22.48a20.87,20.87,0,0,0,28,0l41.08-37.17-.08-.08L739,625.91A46.58,46.58,0,0,0,754.38,591.44Z"/>
|
||||
<path class="cls-4" transform="translate(.02 .11)" d="M541,595.54,527.21,583c-.67-.71-1.35-1.42-2.09-2.09l-14.5-13.09-8.68-7.95-.06,0-167.22-151L525.21,236.42c.09-.08.16-.17.25-.25l14.07-12.73a20.88,20.88,0,0,0,0-31L514.71,170a20.87,20.87,0,0,0-28,0l-41.08,37.18h0L260.85,374.39a46.56,46.56,0,0,0,0,69L445.27,609.91l-.06.05,42.89,39a20.87,20.87,0,0,0,28,0l24.83-22.47A20.87,20.87,0,0,0,541,595.54Z"/>
|
||||
<path d="m173.66 173.36 646.24 642.31" fill="#f00" stroke="#f00" stroke-linecap="round" stroke-width="50"/>
|
||||
<path d="m824.02 175.25-648.03 648.03" fill="none" stroke="#f00" stroke-linecap="round" stroke-width="50"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 3.0 KiB |
@ -1,45 +0,0 @@
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMessageBox>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <Security/Security.h>
|
||||
|
||||
int uninstall();
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
QApplication app{argc, argv};
|
||||
if(QMessageBox::question(nullptr, "Lokinet Uninstaller", "Do You want to uninstall Lokinet?",
|
||||
QMessageBox::Yes|QMessageBox::No)
|
||||
== QMessageBox::Yes)
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
const auto retcode = uninstall();
|
||||
if(retcode == 0)
|
||||
{
|
||||
msgBox.setText("Lokinet has been successfully uninstalled, you may now remove the uninstaller if you wish.");
|
||||
}
|
||||
else
|
||||
{
|
||||
msgBox.setText("Failed to uninstall lokinet");
|
||||
}
|
||||
msgBox.exec();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uninstall()
|
||||
{
|
||||
AuthorizationRef authorizationRef;
|
||||
OSStatus status;
|
||||
|
||||
status = AuthorizationCreate(nullptr, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorizationRef);
|
||||
if(status != 0)
|
||||
return status;
|
||||
char* tool = "/bin/sh";
|
||||
char* args[] = {"/opt/lokinet/bin/lokinet_uninstall.sh", nullptr};
|
||||
FILE* pipe = stdout;
|
||||
|
||||
return AuthorizationExecuteWithPrivileges(authorizationRef, tool, kAuthorizationFlagDefaults, args, &pipe);
|
||||
}
|
||||
|
@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Invoked from cmake as make-ico.sh /path/to/icon.svg /path/to/output.ico
|
||||
svg="$1"
|
||||
out="$2"
|
||||
outdir="$out.d"
|
||||
|
||||
set -e
|
||||
|
||||
sizes=(16 24 32 40 48 64 96 192 256)
|
||||
outs=""
|
||||
|
||||
mkdir -p "${outdir}"
|
||||
for size in "${sizes[@]}"; do
|
||||
outf="${outdir}/${size}x${size}.png"
|
||||
if [ $size -lt 32 ]; then
|
||||
# For 16x16 and 24x24 we crop the image to 3/4 of its regular size before resizing and make
|
||||
# it all white (instead of transparent) which effectively zooms in on it a bit because if we
|
||||
# resize the full icon it ends up a fuzzy mess, while the crop and resize lets us retain
|
||||
# some detail of the logo.
|
||||
convert -background white -resize 512x512 "$svg" -gravity Center -extent 320x320 -resize ${size}x${size} -strip "png32:$outf"
|
||||
else
|
||||
convert -background transparent -resize ${size}x${size} "$svg" -strip "png32:$outf"
|
||||
fi
|
||||
outs="-r $outf $outs"
|
||||
done
|
||||
|
||||
icotool -c -b 32 -o "$out" $outs
|
@ -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>
|
@ -0,0 +1,47 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
set -x
|
||||
|
||||
# Usage: windows-configure.sh [rootdir [builddir]] -DWHATEVER=BLAH ...
|
||||
|
||||
if [ $# -ge 1 ] && [[ "$1" != -* ]]; then
|
||||
root="$1"
|
||||
shift
|
||||
else
|
||||
root="$(dirname $0)"/..
|
||||
fi
|
||||
root="$(readlink -f "$root")"
|
||||
|
||||
if [ $# -ge 1 ] && [[ "$1" != -* ]]; then
|
||||
build="$(readlink -f "$1")"
|
||||
shift
|
||||
else
|
||||
build="$root/build/win32"
|
||||
echo "Setting up build in $build"
|
||||
fi
|
||||
|
||||
mkdir -p "$build"
|
||||
cmake \
|
||||
-S "$root" -B "$build" \
|
||||
-G 'Unix Makefiles' \
|
||||
-DCMAKE_EXE_LINKER_FLAGS=-fstack-protector \
|
||||
-DCMAKE_CXX_FLAGS=-fdiagnostics-color=always \
|
||||
-DCMAKE_TOOLCHAIN_FILE="$root/contrib/cross/mingw64.cmake" \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DBUILD_STATIC_DEPS=ON \
|
||||
-DBUILD_PACKAGE=ON \
|
||||
-DBUILD_SHARED_LIBS=OFF \
|
||||
-DBUILD_TESTING=OFF \
|
||||
-DBUILD_LIBLOKINET=OFF \
|
||||
-DWITH_TESTS=OFF \
|
||||
-DWITH_BOOTSTRAP=OFF \
|
||||
-DNATIVE_BUILD=OFF \
|
||||
-DSTATIC_LINK=ON \
|
||||
-DWITH_SYSTEMD=OFF \
|
||||
-DFORCE_OXENMQ_SUBMODULE=ON \
|
||||
-DFORCE_OXENC_SUBMODULE=ON \
|
||||
-DFORCE_FMT_SUBMODULE=ON \
|
||||
-DFORCE_SPDLOG_SUBMODULE=ON \
|
||||
-DFORCE_NLOHMANN_SUBMODULE=ON \
|
||||
-DWITH_LTO=OFF \
|
||||
"$@"
|
@ -1,92 +0,0 @@
|
||||
#include <llarp/config/config.hpp>
|
||||
#include <llarp/router_contact.hpp>
|
||||
#include <llarp/util/logging/logger.hpp>
|
||||
#include <llarp/util/logging/ostream_logger.hpp>
|
||||
|
||||
#include <cxxopts.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace
|
||||
{
|
||||
bool
|
||||
dumpRc(const std::vector<std::string>& files)
|
||||
{
|
||||
nlohmann::json result;
|
||||
for (const auto& file : files)
|
||||
{
|
||||
llarp::RouterContact rc;
|
||||
const bool ret = rc.Read(file.c_str());
|
||||
|
||||
if (ret)
|
||||
{
|
||||
result[file] = rc.ToJson();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "file = " << file << " was not a valid rc file\n";
|
||||
}
|
||||
}
|
||||
std::cout << result << "\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
cxxopts::Options options(
|
||||
"lokinetctl",
|
||||
"LokiNET is a free, open source, private, "
|
||||
"decentralized, \"market based sybil resistant\" "
|
||||
"and IP based onion routing network");
|
||||
|
||||
options.add_options()("v,verbose", "Verbose", cxxopts::value<bool>())(
|
||||
"h,help", "help", cxxopts::value<bool>())(
|
||||
"c,config",
|
||||
"config file",
|
||||
cxxopts::value<std::string>()->default_value(llarp::GetDefaultConfigPath().string()))(
|
||||
"dump", "dump rc file", cxxopts::value<std::vector<std::string>>(), "FILE");
|
||||
|
||||
try
|
||||
{
|
||||
const auto result = options.parse(argc, argv);
|
||||
|
||||
if (result.count("verbose") > 0)
|
||||
{
|
||||
SetLogLevel(llarp::eLogDebug);
|
||||
llarp::LogContext::Instance().logStream =
|
||||
std::make_unique<llarp::OStreamLogStream>(true, std::cerr);
|
||||
llarp::LogDebug("debug logging activated");
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLogLevel(llarp::eLogError);
|
||||
llarp::LogContext::Instance().logStream =
|
||||
std::make_unique<llarp::OStreamLogStream>(true, std::cerr);
|
||||
}
|
||||
|
||||
if (result.count("help") > 0)
|
||||
{
|
||||
std::cout << options.help() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (result.count("dump") > 0)
|
||||
{
|
||||
if (!dumpRc(result["dump"].as<std::vector<std::string>>()))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const cxxopts::OptionParseException& ex)
|
||||
{
|
||||
std::cerr << ex.what() << std::endl;
|
||||
std::cout << options.help() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
# DNS in Lokinet
|
||||
|
||||
Lokinet uses dns are its primary interface for resolving, mapping and querying resources inside of lokinet.
|
||||
This was done not because DNS is *good* protocol, but because there is almost no relevent userland applications that are incapable of interacting with DNS, across every platform.
|
||||
Using DNS in lokinet allows for the most zero config setup possible with the current set of standard protocols.
|
||||
|
||||
Lokinet provides 2 internal gtld, `.loki` and `.snode`
|
||||
|
||||
## .snode
|
||||
|
||||
The `.snode` gtld is used to address a lokinet router in the form of `<zbase32 encoded public ed25519 identity key>.snode`.
|
||||
Traffic bound to a `.snode` tld will have its source authenticatable only if it originates from another valid lokinet router.
|
||||
Clients can also send traffic to and from addresses mapped to `.snode` addresses, but the source address on the service node side is ephemeral.
|
||||
In both cases, ip traffic to addresses mapped to `.snode` addresses will have the destination ip rewritten by the lokinet router to be its local interface ip, this ensures traffic stays on the lokinet router' interface for snode traffic and preventing usage as an exit node.
|
||||
|
||||
## .loki
|
||||
|
||||
The `.loki` gtld is used to address anonymously published routes to lokinet clients on the network.
|
||||
|
||||
<!-- (todo: keyblinding info) -->
|
||||
|
||||
## What RR are provided?
|
||||
|
||||
All `.loki` domains by default have the following dns rr synthesized by lokinet:
|
||||
|
||||
* `A` record for initiating address mapping
|
||||
* `MX` record pointing to the synthesizesd `A` record
|
||||
* free wildcard entries for all of the above.
|
||||
|
||||
Wildard entries are currently only pointing
|
||||
|
||||
All `.snode` domains have by defult just an `A` record for initiating address mapping.
|
||||
|
||||
Additionally both `.loki` and `.snode` can optionally provide multiple `SRV` records to advertise existence of services on or off of the name.
|
||||
|
||||
<!-- (//todo: document and verify srv record limitations) -->
|
@ -0,0 +1,19 @@
|
||||
## onion routing overview
|
||||
|
||||
<!-- todo: how is traffic transported (encryption, onion etc.) for somebody knowing nothing about LLARP) -->
|
||||
|
||||
<!-- todo: are there any techniques available to circumvent blocking of Lokinet traffic? (not at the moment) -->
|
||||
|
||||
<!-- todo: how does path multiplexing work? -->
|
||||
|
||||
## endpoint zmq api
|
||||
|
||||
<!-- todo: endpoint authentication (dns records) -->
|
||||
|
||||
## DNS
|
||||
|
||||
<!-- todo: how does LN handle DNS requests -->
|
||||
|
||||
<!-- todo: how are loki addresses looked up -->
|
||||
|
||||
<!-- todo: hoes does ONS work right now (info on lookup redundancy) -->
|
@ -1,3 +1,42 @@
|
||||
# How Do I use lokinet?
|
||||
# What does Lokinet actually do?
|
||||
|
||||
`// TODO: this`
|
||||
Lokinet is an onion routed authenticated unicast IP network. It exposes an IP tunnel to the user and provides a dns resolver that maps `.loki` and `.snode` gtld onto a user defined ip range.
|
||||
|
||||
Lokinet allows users to tunnel arbitrary ip ranges to go to a `.loki` address to act as a tunnel broker via another network accessible via another lokinet client. This is commonly known as an "exit node" but the way lokinet does this is much more generic so that term is not very accurate given what it actually does.
|
||||
|
||||
The `.snode` gtld refers to a router on the network by its public ed25519 key.
|
||||
|
||||
The `.loki` gtld refers to clients that publish the existence anonymously to the network by their ed25519 public key. (`.loki` also has the ability to use short names resolved via external consensus method, like a blockchain).
|
||||
|
||||
# How Do I use Lokinet?
|
||||
|
||||
set system dns resolver to use the dns resolver provided by lokinet, make sure the upstream dns provider that lokinet uses for non lokinet gtlds is set as desired (see lokinet.ini `[dns]` section)
|
||||
|
||||
configure exit traffic provider if you want to tunnel ip traffic via lokinet, by default this is off as we cannot provide a sane defualt that makes everyone happy. to enable an exit node, see lokinet.ini `[network]` section, add multiple `exit-node=exitaddrgoeshere.loki` lines for each endpoint you want to use for exit traffic. each `exit-node` entry will be used to randomly stripe across per IP you are sending to.
|
||||
|
||||
note: per flow (ip+proto/port) isolation is trivial on a technical level but currently not implemented at this time.
|
||||
|
||||
# Can I run lokinet on a soho router
|
||||
|
||||
Yes and that is the best way to run it in practice.
|
||||
|
||||
## The "easy" way
|
||||
|
||||
We have a community maintained solution for ARM SBCs like rasperry pi: https://github.com/necro-nemesis/LabyrinthAP
|
||||
|
||||
## The "fun" way (DIY)
|
||||
|
||||
It is quite nice to DIY. if you choose to do so there is some assembly required:
|
||||
|
||||
on the lokinet side, make sure that the...
|
||||
|
||||
* ip ranges for `.loki` and `.snode` are statically set (see lokinet.ini `[network]` section `ifaddr=` option)
|
||||
* network interace used by lokinet is statically set (see lokinet.ini `[network]` section `ifname=` option)
|
||||
* dns socket is bound to an address the soho router's dns resolver can talk to, see `[dns]` section `bind=` option)
|
||||
|
||||
on the soho router side:
|
||||
|
||||
* route queries for `.loki` and `.snode` gtld to go to lokinet dns on soho router's dns resolver
|
||||
* use dhcp options to set dns to use the soho router's dns resolver
|
||||
* make sure that the ip ranges for lokinet are reachable via the LAN interface
|
||||
* if you are tunneling over an exit ensure that LAN traffic will only forward to go over the lokinet vpn interface
|
||||
|
@ -0,0 +1,173 @@
|
||||
# Installing
|
||||
|
||||
If you are simply looking to install Lokinet and don't want to compile it yourself we provide several options for platforms to run on:
|
||||
|
||||
Tier 1:
|
||||
|
||||
* [Linux](#linux-install)
|
||||
* [Android](#apk-install)
|
||||
* [Windows](#windows-install)
|
||||
* [MacOS](#macos-install)
|
||||
|
||||
Tier 2:
|
||||
|
||||
* [FreeBSD](#freebsd-install)
|
||||
|
||||
Currently Unsupported Platforms: (maintainers welcome)
|
||||
|
||||
* Apple iPhone
|
||||
* Homebrew
|
||||
* \[Insert Flavor of the Month windows package manager here\]
|
||||
|
||||
|
||||
## Official Builds
|
||||
|
||||
### Windows / MacOS <span id="windows-install" /> <span id="macos-install" />
|
||||
|
||||
You can get the latest stable release for lokinet on windows or macos from https://lokinet.org/ or check the [releases page on github](https://github.com/oxen-io/lokinet/releases).
|
||||
|
||||
### Linux <span id="linux-install" />
|
||||
|
||||
You do not have to build from source if you do not wish to, we provide [apt](#deb-install) and [rpm](#rpm-install) repos.
|
||||
|
||||
#### APT repository <span id="deb-install" />
|
||||
|
||||
You can install debian packages from `deb.oxen.io` by adding the apt repo to your system.
|
||||
|
||||
$ sudo curl -so /etc/apt/trusted.gpg.d/oxen.gpg https://deb.oxen.io/pub.gpg
|
||||
$ echo "deb https://deb.oxen.io $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/oxen.list
|
||||
|
||||
This apt repo is also available via lokinet at `http://deb.loki`
|
||||
|
||||
Once added you can install lokinet with:
|
||||
|
||||
$ sudo apt update
|
||||
$ sudo apt install lokinet
|
||||
|
||||
When running from debian package the following steps are not needed as it is already running and ready to use. You can stop/start/restart it using `systemctl start lokinet`, `systemctl stop lokinet`, etc.
|
||||
|
||||
#### RPM <span id="rpm-install" />
|
||||
|
||||
We also provide an RPM repo, see `rpm.oxen.io`, also available on lokinet at `rpm.loki`
|
||||
|
||||
## Bleeding Edge dev builds <span id="ci-builds" />
|
||||
|
||||
automated builds from dev branches for the brave or impatient can be found from our CI pipeline [here](https://oxen.rocks/oxen-io/lokinet/). (warning: these nightly builds may or may not consume your first born child.)
|
||||
|
||||
## Building
|
||||
|
||||
Build requirements:
|
||||
|
||||
* Git
|
||||
* CMake
|
||||
* C++ 17 capable C++ compiler
|
||||
* libuv >= 1.27.0
|
||||
* libsodium >= 1.0.18
|
||||
* libssl (for lokinet-bootstrap)
|
||||
* libcurl (for lokinet-bootstrap)
|
||||
* libunbound
|
||||
* libzmq
|
||||
* cppzmq
|
||||
|
||||
### Linux Compile
|
||||
|
||||
If you want to build from source: <span id="linux-compile" />
|
||||
|
||||
$ sudo apt install build-essential cmake git libcap-dev pkg-config automake libtool libuv1-dev libsodium-dev libzmq3-dev libcurl4-openssl-dev libevent-dev nettle-dev libunbound-dev libssl-dev nlohmann-json3-dev
|
||||
$ git clone --recursive https://github.com/oxen-io/lokinet
|
||||
$ cd lokinet
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
$ cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF
|
||||
$ make -j$(nproc)
|
||||
$ sudo make install
|
||||
|
||||
set up the initial configs:
|
||||
|
||||
$ lokinet -g
|
||||
$ lokinet-bootstrap
|
||||
|
||||
after you create default config, run it:
|
||||
|
||||
$ lokinet
|
||||
|
||||
This requires the binary to have the proper capabilities which is usually set by `make install` on the binary. If you have errors regarding permissions to open a new interface this can be resolved using:
|
||||
|
||||
$ sudo setcap cap_net_admin,cap_net_bind_service=+eip /usr/local/bin/lokinet
|
||||
|
||||
|
||||
#### Arch Linux <span id="mom-cancel-my-meetings-arch-linux-broke-again" />
|
||||
|
||||
Due to [circumstances beyond our control](https://github.com/oxen-io/lokinet/discussions/1823) a working `PKGBUILD` can be found [here](https://raw.githubusercontent.com/oxen-io/lokinet/makepkg/contrib/archlinux/PKGBUILD).
|
||||
|
||||
#### Cross Compile For Linux <span id="linux-cross" />
|
||||
|
||||
current cross targets:
|
||||
|
||||
* aarch64-linux-gnu
|
||||
* arm-linux-gnueabihf
|
||||
* mips-linux-gnu
|
||||
* mips64-linux-gnuabi64
|
||||
* mipsel-linux-gnu
|
||||
* powerpc64le-linux-gnu
|
||||
|
||||
install the toolchain (this one is for `aarch64-linux-gnu`, you can provide your own toolchain if you want)
|
||||
|
||||
$ sudo apt install g{cc,++}-aarch64-linux-gnu
|
||||
|
||||
build 1 or many cross targets:
|
||||
|
||||
$ ./contrib/cross.sh arch_1 arch_2 ... arch_n
|
||||
|
||||
### Building For Windows <span id="win32-cross" />
|
||||
|
||||
windows builds are cross compiled from debian/ubuntu linux
|
||||
|
||||
additional build requirements:
|
||||
|
||||
* nsis
|
||||
* cpack
|
||||
|
||||
setup:
|
||||
|
||||
$ sudo apt install build-essential cmake git pkg-config mingw-w64 nsis cpack automake libtool
|
||||
$ sudo update-alternatives --set x86_64-w64-mingw32-gcc /usr/bin/x86_64-w64-mingw32-gcc-posix
|
||||
$ sudo update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix
|
||||
|
||||
building:
|
||||
|
||||
$ git clone --recursive https://github.com/oxen-io/lokinet
|
||||
$ cd lokinet
|
||||
$ ./contrib/windows.sh
|
||||
|
||||
### Compiling for MacOS <span id="mac-compile" />
|
||||
|
||||
Source code compilation of Lokinet by end users is not supported or permitted by apple on their platforms, see [this](../contrib/macos/README.txt) for more information.
|
||||
|
||||
If you find this disagreeable consider using a platform that permits compiling from source.
|
||||
|
||||
### FreeBSD <span id="freebsd-install" />
|
||||
|
||||
Currently has no VPN Platform code, see issue `#1513`
|
||||
|
||||
build:
|
||||
|
||||
$ pkg install cmake git pkgconf
|
||||
$ git clone --recursive https://github.com/oxen-io/lokinet
|
||||
$ cd lokinet
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
$ cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DSTATIC_LINK=ON -DBUILD_STATIC_DEPS=ON ..
|
||||
$ make
|
||||
|
||||
install (root):
|
||||
|
||||
# make install
|
||||
|
||||
### Android <span id="apk-install" />
|
||||
|
||||
We have an Android APK for lokinet VPN via android VPN API.
|
||||
|
||||
Coming to F-Droid whenever that happens. [[issue]](https://github.com/oxen-io/lokinet-flutter-app/issues/8)
|
||||
|
||||
* [source code](https://github.com/oxen-io/lokinet-flutter-app)
|
@ -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,110 @@
|
||||
# Lokinet project structure
|
||||
|
||||
this codebase is a bit large. this is a high level map of the current code structure.
|
||||
|
||||
## lokinet executable main functions `(/daemon)`
|
||||
|
||||
* `lokinet.cpp`: lokinet daemon executable
|
||||
* `lokinet.swift`: macos sysex/appex executable
|
||||
* `lokinet-vpn.cpp`: lokinet rpc tool for controlling exit node usage
|
||||
* `lokinet-bootstrap.cpp`: legacy util for windows, downloads a bootstrap file via https
|
||||
|
||||
|
||||
## lokinet public headers `(/include)`
|
||||
|
||||
`lokinet.h and lokinet/*.h`: C headers for embedded lokinet
|
||||
|
||||
`llarp.hpp`: semi-internal C++ header for lokinet executables
|
||||
|
||||
|
||||
## lokinet core library `(/llarp)`
|
||||
|
||||
* `/llarp`: contains a few straggling compilation units
|
||||
* `/llarp/android`: android platform compat shims
|
||||
* `/llarp/apple`: all apple platform specific code
|
||||
* `/llarp/config`: configuration structs, generation/parsing/validating of config files
|
||||
* `/llarp/consensus`: network consenus and inter relay testing
|
||||
* `/llarp/constants`: contains all compile time constants
|
||||
* `/llarp/crypto`: cryptography interface and implementation, includes various secure helpers
|
||||
* `/llarp/dht`: dht message structs, parsing, validation and handlers of dht related parts of the protocol
|
||||
* `/llarp/dns`: dns subsytem, dns udp wire parsers, resolver, server, rewriter/interceptor, the works
|
||||
* `/llarp/ev`: event loop interfaces and implementations
|
||||
* `/llarp/exit`: `.snode` endpoint "backend"
|
||||
* `/llarp/handlers`: packet endpoint "frontends"
|
||||
* `/llarp/iwp`: "internet wire protocol", hacky homegrown durable udp wire protocol used in lokinet
|
||||
* `/llarp/link`: linklayer (node to node) communcation subsystem
|
||||
* `/llarp/messages`: linklayer message parsing and handling
|
||||
* `/llarp/net`: wrappers and helpers for ip addresses / ip ranges / sockaddrs, hides platform specific implemenation details
|
||||
* `/llarp/path`: onion routing path logic, both client and relay side, path selection algorithms.
|
||||
* `/llarp/peerstats`: deprecated
|
||||
* `/llarp/quic`: plainquic shims for quic protocol inside lokinet
|
||||
* `/llarp/router`: the relm of the god objects
|
||||
* `/llarp/routing`: routing messages (onion routed messages sent over paths), parsing, validation and handler interfaces.
|
||||
* `/llarp/rpc`: lokinet zmq rpc server and zmq client for externalizing logic (like with blockchain state and custom `.loki` endpoint orchestration)
|
||||
* `/llarp/service`: `.loki` endpoint "backend"
|
||||
* `/llarp/simulation`: network simulation shims
|
||||
* `/llarp/tooling`: network simulation tooling
|
||||
* `/llarp/util`: utility function dumping ground
|
||||
* `/llarp/vpn`: vpn tunnel implemenation for each supported platform
|
||||
* `/llarp/win32`: windows specific code
|
||||
|
||||
|
||||
## component relations
|
||||
|
||||
### `/llarp/service` / `/llarp/handlers` / `/llarp/exit`
|
||||
|
||||
for all codepaths for traffic over lokinet, there is 2 parts, the "frontend" and the "backend".
|
||||
|
||||
the "backend" is responsible for sending and recieving data inside lokinet using our internal formats via paths, it handles flow management, lookups, timeouts, handover, and all state we have inside lokinet.
|
||||
|
||||
the "fontend", is a translation layer that takes in IP Packets from the OS, and send it to the backend to go where ever it wants to go, and recieves data from the "backend" and sends it to the OS as an IP Packet.
|
||||
|
||||
there are 2 'backends': `.snode` and `.loki`
|
||||
|
||||
there are 2 'frontends': "tun" (generic OS vpn interface) and "null" (does nothing)
|
||||
|
||||
* `//TODO: the backends need to be split up into multiple sub components as they are a kitchen sink.`
|
||||
* `//TODO: the frontends blend into the backend too much and need to have their boundery clearer.`
|
||||
|
||||
|
||||
### `/llarp/ev` / `/llarp/net` / `/llarp/vpn`
|
||||
|
||||
these contain most of the os/platform specific bits
|
||||
|
||||
* `//TODO: untangle these`
|
||||
|
||||
|
||||
### `/llarp/link` / `/llarp/iwp`
|
||||
|
||||
node to node traffic logic and wire protocol dialects
|
||||
|
||||
* `//TODO: make better definitions of interfaces`
|
||||
* `//TODO: separte implementation details from interfaces`
|
||||
|
||||
|
||||
## platform contrib code `(/contrib)`
|
||||
|
||||
grab bag directory for non core related platform specific non source code
|
||||
|
||||
* `/contrib/format.sh`: clang-format / jsonnetfmt / swiftformat helper, will check or correct code style.
|
||||
|
||||
system layer and packaging related:
|
||||
|
||||
* `/contrib/NetworkManager`
|
||||
* `/contrib/apparmor`
|
||||
* `/contrib/systemd-resolved`
|
||||
* `/contrib/lokinet-resolvconf`
|
||||
* `/contrib/bootstrap`
|
||||
|
||||
build shims / ci helpers
|
||||
|
||||
* `/contrib/ci`
|
||||
* `/contrib/patches`
|
||||
* `/contrib/cross`
|
||||
* `/contrib/android.sh`
|
||||
* `/contrib/android-configure.sh`
|
||||
* `/contrib/windows.sh`
|
||||
* `/contrib/windows-configure.sh`
|
||||
* `/contrib/mac.sh`
|
||||
* `/contrib/ios.sh`
|
||||
* `/contrib/cross.sh`
|
@ -1 +0,0 @@
|
||||
Subproject commit cac99da8dc88be719a728dc1b597b0ac307c1800
|
@ -1 +1 @@
|
||||
Subproject commit 79193e58fb26624d40cd2e95156f78160f2b9b3e
|
||||
Subproject commit 707a83609fb64d09b61ed1e56c82bf692050d2a1
|
@ -0,0 +1 @@
|
||||
Subproject commit 9f2323a2db5fc54fe8394892769eff859967f735
|
@ -1 +1 @@
|
||||
Subproject commit eadb37c7654150bef18497773718f15ef843734a
|
||||
Subproject commit ac6ef82ff6fd20437b7d073466dbef82a95a2173
|
@ -0,0 +1,13 @@
|
||||
directory for git submodules
|
||||
|
||||
* cpr: curl for people, used by lokinet-bootstrap toolchain (to be removed)
|
||||
* cxxopts: cli argument parser (to be removed)
|
||||
* ghc-filesystem: `std::filesystem` shim lib for older platforms (like macos)
|
||||
* ngtcp2: quic implementation
|
||||
* nlohmann: json parser
|
||||
* oxen-encoding: [bencode](https://www.bittorrent.org/beps/bep_0003.html#bencoding)/endian header-only library
|
||||
* oxen-logging: spdlog wrapper library
|
||||
* oxen-mq: zmq wrapper library for threadpool and rpc
|
||||
* pybind11: for pybind modules
|
||||
* sqlite_orm: for peer stats db
|
||||
* uvw: libuv header only library for main event loop
|
@ -0,0 +1 @@
|
||||
Subproject commit 7b0f1aacdf79b558adfc39dc9cccb7e348aeec03
|
@ -0,0 +1 @@
|
||||
jni binding for lokinet vpn using android vpn api
|
@ -1,25 +0,0 @@
|
||||
#include "apple_logger.hpp"
|
||||
|
||||
namespace llarp::apple
|
||||
{
|
||||
void
|
||||
NSLogStream::PreLog(
|
||||
std::stringstream& ss,
|
||||
LogLevel lvl,
|
||||
std::string_view fname,
|
||||
int lineno,
|
||||
const std::string& nodename) const
|
||||
{
|
||||
ss << "[" << LogLevelToString(lvl) << "] ";
|
||||
ss << "[" << nodename << "]"
|
||||
<< "(" << thread_id_string() << ") " << log_timestamp() << " " << fname << ":" << lineno
|
||||
<< "\t";
|
||||
}
|
||||
|
||||
void
|
||||
NSLogStream::Print(LogLevel, std::string_view, const std::string& msg)
|
||||
{
|
||||
ns_logger(msg.c_str());
|
||||
}
|
||||
|
||||
} // namespace llarp::apple
|
@ -1,40 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <llarp/util/logging/logger.hpp>
|
||||
#include <llarp/util/logging/logstream.hpp>
|
||||
|
||||
namespace llarp::apple
|
||||
{
|
||||
struct NSLogStream : public ILogStream
|
||||
{
|
||||
using ns_logger_callback = void (*)(const char* log_this);
|
||||
|
||||
NSLogStream(ns_logger_callback logger) : ns_logger{logger}
|
||||
{}
|
||||
|
||||
void
|
||||
PreLog(
|
||||
std::stringstream& s,
|
||||
LogLevel lvl,
|
||||
std::string_view fname,
|
||||
int lineno,
|
||||
const std::string& nodename) const override;
|
||||
|
||||
void
|
||||
Print(LogLevel lvl, std::string_view tag, const std::string& msg) override;
|
||||
|
||||
void
|
||||
PostLog(std::stringstream&) const override
|
||||
{}
|
||||
|
||||
void
|
||||
ImmediateFlush() override
|
||||
{}
|
||||
|
||||
void Tick(llarp_time_t) override
|
||||
{}
|
||||
|
||||
private:
|
||||
ns_logger_callback ns_logger;
|
||||
};
|
||||
} // namespace llarp::apple
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue