Compare commits

...

4 Commits

Author SHA1 Message Date
Tom Burgin
d0ede18bf4 MOLCertificate --> 1.9 (#290) 2018-07-06 12:56:15 -04:00
Alessandro Gario
6d223aea03 Various fixes (documentation, and an additional check on the JSON received from the syncserver) (#288)
* santa-driver: Fix documentation warnings
* SantaCache: Fix documentation warnings
* santactl: Always make sure that the syncserver JSON is a dictionary
2018-07-06 09:42:22 -04:00
Alessandro Gario
f7986b0a05 Update MOLXPCConnection; add support for unprivileged XPC interfaces (#287)
* Update MOLXPCConnection; add support for unprivileged XPC interfaces

* Code review changes
2018-07-05 17:20:49 -04:00
Alessandro Gario
629e70287c Add CMake support, implement fuzzers (#284)
The new CMake project allows the user to select which SDK version
to use. The Xcode path is also configurable to support non-standard
installation paths and/or systems with multiple versions installed.

Code signing can now be configured via command line, using the
CODESIGN_IDENTITY environment variable.

New fuzzing targets (libFuzzer)
 - SantaCache
 - santactl
 - santad

New make targets:
 - tests: Runs the tests
 - fuzz: Runs the fuzzer
 - redist: Regenerates the redistributable folder
 - install: Installs Santa
2018-06-29 14:15:16 -04:00
53 changed files with 2023 additions and 156 deletions

133
CMakeLists.txt Normal file
View File

@@ -0,0 +1,133 @@
cmake_minimum_required(VERSION 3.10.0)
execute_process(
COMMAND git fetch --tags --all
COMMAND git describe --tags --always --abbrev=0
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_VARIABLE SANTA_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND xcode-select -p
OUTPUT_VARIABLE DEFAULT_XCODE_ROOT_FOLDER
)
string(STRIP "${DEFAULT_XCODE_ROOT_FOLDER}" DEFAULT_XCODE_ROOT_FOLDER)
add_custom_target(tests)
function(AddTestTarget target_name run_as_root)
if(run_as_root)
add_custom_target(
"${target_name}_runner"
COMMAND sudo $<TARGET_FILE:${target_name}>
COMMENT "Running ${target_name}_runner as root"
)
else()
add_custom_target(
"${target_name}_runner"
COMMAND $<TARGET_FILE:${target_name}>
)
endif()
add_dependencies(tests "${target_name}_runner")
endfunction()
add_custom_target(fuzz)
function(AddFuzzTarget target_name max_len max_total_time run_as_root)
add_custom_command(TARGET "${target_name}" POST_BUILD
COMMAND codesign --force --verify --verbose --sign "${CODESIGN_IDENTITY}" $<TARGET_FILE:${target_name}>
COMMENT "Signing ${target_name} with the following identity: ${CODESIGN_IDENTITY}"
)
if(${run_as_root})
set(sudo_command "sudo")
else()
set(sudo_command "")
endif()
add_custom_target(
"${target_name}_runner"
COMMAND "${CMAKE_COMMAND}" -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/${target_name}_corpus"
COMMAND ${sudo_command} $<TARGET_FILE:${target_name}> -max_len=${max_len} -max_total_time=${max_total_time} "${CMAKE_CURRENT_BINARY_DIR}/${target_name}_corpus" "${CMAKE_CURRENT_SOURCE_DIR}/${target_name}_seed_corpus"
COMMENT "Running fuzzer: ${target_name}"
)
add_dependencies("${target_name}_runner" "${target_name}")
add_dependencies(fuzz "${target_name}_runner")
endfunction()
function(main)
if("${CMAKE_BUILD_TYPE}" STREQUAL "")
set(CMAKE_BUILD_TYPE RelWithDebInfo)
endif()
if(NOT DEFINED CODESIGN_IDENTITY)
if ("$ENV{CODESIGN_IDENTITY}" STREQUAL "")
message(FATAL_ERROR "Please define CODESIGN_IDENTITY - You can either use an environment variable or pass it to CMake with -DCODESIGN_IDENTITY=identity. If you are using sudo, make sure to keep the variable defined")
endif()
set(CODESIGN_IDENTITY "$ENV{CODESIGN_IDENTITY}")
endif()
if(NOT MACOSX_VERSION_MIN)
set(MACOSX_VERSION_MIN 10.9)
endif()
if(NOT MACOSX_SDK_VERSION)
set(sdk_version_name "Latest")
else()
set(sdk_version_name "${MACOSX_SDK_VERSION}")
endif()
if(NOT XCODE_ROOT_FOLDER)
set(XCODE_ROOT_FOLDER "${DEFAULT_XCODE_ROOT_FOLDER}")
endif()
message(STATUS "MACOSX_VERSION_MIN: ${MACOSX_VERSION_MIN}")
message(STATUS "MACOSX_SDK_VERSION: ${sdk_version_name}")
message(STATUS "XCODE_ROOT_FOLDER: ${XCODE_ROOT_FOLDER}")
message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
message(STATUS "SANTA_VERSION: ${SANTA_VERSION}")
add_subdirectory(CocoaPods)
add_subdirectory(Source/santad)
add_subdirectory(Source/santactl)
add_subdirectory(Source/santabs)
add_subdirectory(Source/SantaGUI)
add_subdirectory(Source/santa-driver)
add_subdirectory(Fuzzing)
add_subdirectory(Tests)
set(redist_folder_path "${CMAKE_BINARY_DIR}/redist")
add_custom_command(
OUTPUT "${redist_folder_path}/conf/install.sh"
# Copy the binaries
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_BINARY_DIR}/Source/SantaGUI/Santa.app" "${redist_folder_path}/binaries/Santa.app"
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_BINARY_DIR}/Source/santa-driver/santa-driver.kext" "${redist_folder_path}/binaries/santa-driver.kext"
# Copy the configuration files
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_SOURCE_DIR}/Conf" "${redist_folder_path}/conf"
COMMAND "${CMAKE_COMMAND}" -E remove_directory "${redist_folder_path}/conf/Package"
COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_SOURCE_DIR}/Docs/deployment/com.google.santa.example.mobileconfig" "${redist_folder_path}/conf"
COMMENT "Generating redistributable package"
)
add_custom_target(redist DEPENDS "${redist_folder_path}/conf/install.sh")
add_dependencies(redist santad santa-driver santactl santabs Santa)
install(FILES Conf/com.google.santad.plist DESTINATION /Library/LaunchDaemons)
install(FILES Conf/com.google.santagui.plist DESTINATION /Library/LaunchAgents)
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E echo To finalize the installation, run the following commands)")
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E echo sudo /sbin/kextload /Library/Extensions/santa-driver.kext)")
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E echo sudo /bin/launchctl load /Library/LaunchDaemons/com.google.santad.plist)")
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E echo sudo /bin/launchctl asuser `/usr/bin/stat -f '%u' /dev/console` /bin/launchctl load /Library/LaunchAgents/com.google.santagui.plist)")
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E echo Configuration guide available on ReadTheDocs - https://santa.readthedocs.io/en/latest/deployment/configuration/)")
endfunction()
main()

195
CocoaPods/CMakeLists.txt Normal file
View File

@@ -0,0 +1,195 @@
cmake_minimum_required(VERSION 3.10.0)
project(CocoaPods)
function(main)
add_custom_command(
OUTPUT "${CMAKE_SOURCE_DIR}/Pods/Manifest.lock"
COMMAND pod repo update && pod install
DEPENDS "${CMAKE_SOURCE_DIR}/Podfile"
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
COMMENT "Fetching CocoaPods dependencies"
VERBATIM
)
add_custom_target("${PROJECT_NAME}"
DEPENDS "${CMAKE_SOURCE_DIR}/Pods/Manifest.lock"
)
ImportCocoaPodsLibrary(
FMDB
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb"
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb/FMDatabase.h"
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb/FMResultSet.h"
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb/FMDatabasePool.h"
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb/FMDatabaseQueue.h"
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb/FMDB.h"
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb/FMDatabaseAdditions.h"
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb/FMDatabaseQueue.m"
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb/FMDatabaseAdditions.m"
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb/FMDatabase.m"
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb/FMDatabasePool.m"
"${CMAKE_SOURCE_DIR}/Pods/FMDB/src/fmdb/FMResultSet.m"
)
target_link_libraries(FMDB PUBLIC sqlite3 "-framework Cocoa")
ImportCocoaPodsLibrary(
MOLCertificate
"${CMAKE_SOURCE_DIR}/Pods/MOLCertificate/Source/MOLCertificate"
"${CMAKE_SOURCE_DIR}/Pods/MOLCertificate/Source/MOLCertificate/MOLCertificate.m"
"${CMAKE_SOURCE_DIR}/Pods/MOLCertificate/Source/MOLCertificate/MOLCertificate.h"
)
target_link_libraries(MOLCertificate PUBLIC "-framework Security" "-framework Cocoa")
ImportCocoaPodsLibrary(
MOLCodesignChecker
"${CMAKE_SOURCE_DIR}/Pods/MOLCodesignChecker/Source/MOLCodesignChecker"
"${CMAKE_SOURCE_DIR}/Pods/MOLCodesignChecker/Source/MOLCodesignChecker/MOLCodesignChecker.h"
"${CMAKE_SOURCE_DIR}/Pods/MOLCodesignChecker/Source/MOLCodesignChecker/MOLCodesignChecker.m"
)
target_link_libraries(MOLCodesignChecker PUBLIC "-framework Security" "-framework Cocoa")
ImportCocoaPodsLibrary(
MOLAuthenticatingURLSession
"${CMAKE_SOURCE_DIR}/Pods/MOLAuthenticatingURLSession/Source/MOLAuthenticatingURLSession"
"${CMAKE_SOURCE_DIR}/Pods/MOLAuthenticatingURLSession/Source/MOLAuthenticatingURLSession/MOLAuthenticatingURLSession.m"
"${CMAKE_SOURCE_DIR}/Pods/MOLAuthenticatingURLSession/Source/MOLAuthenticatingURLSession/MOLDERDecoder.m"
"${CMAKE_SOURCE_DIR}/Pods/MOLAuthenticatingURLSession/Source/MOLAuthenticatingURLSession/MOLDERDecoder.h"
"${CMAKE_SOURCE_DIR}/Pods/MOLAuthenticatingURLSession/Source/MOLAuthenticatingURLSession/MOLAuthenticatingURLSession.h"
)
target_link_libraries(MOLAuthenticatingURLSession PUBLIC "-framework Security" MOLCertificate "-framework Cocoa")
ImportCocoaPodsLibrary(
MOLFCMClient
"${CMAKE_SOURCE_DIR}/Pods/MOLFCMClient/MOLFCMClient"
"${CMAKE_SOURCE_DIR}/Pods/MOLFCMClient/Source/MOLFCMClient/MOLFCMClient.m"
"${CMAKE_SOURCE_DIR}/Pods/MOLFCMClient/Source/MOLFCMClient/MOLFCMClient.h"
)
target_link_libraries(MOLFCMClient PUBLIC MOLCertificate MOLAuthenticatingURLSession "-framework Cocoa")
target_compile_options(MOLFCMClient PRIVATE -fobjc-weak)
ImportCocoaPodsLibrary(
MOLXPCConnection
"${CMAKE_SOURCE_DIR}/Pods/MOLXPCConnection/Source/MOLXPCConnection"
"${CMAKE_SOURCE_DIR}/Pods/MOLXPCConnection/Source/MOLXPCConnection/MOLXPCConnection.h"
"${CMAKE_SOURCE_DIR}/Pods/MOLXPCConnection/Source/MOLXPCConnection/MOLXPCConnection.m"
)
target_link_libraries(MOLXPCConnection PUBLIC "-framework Cocoa")
ImportCocoaPodsLibrary(
OCMock
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMExceptionReturnValueProvider.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMBlockCaller.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMExpectationRecorder.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMockObject.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMArgAction.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMMacroState.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMRealObjectForwarder.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMInvocationStub.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCPartialMockObject.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMock.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMStubRecorder.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMRecorder.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMInvocationExpectation.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMFunctions.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMIndirectReturnValueProvider.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCProtocolMockObject.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMBlockArgCaller.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMReturnValueProvider.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMBoxedReturnValueProvider.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCClassMockObject.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/NSObject+OCMAdditions.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMInvocationMatcher.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMPassByRefSetter.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMArg.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/NSNotificationCenter+OCMAdditions.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMObserverRecorder.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMNotificationPoster.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMVerifier.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMConstraint.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMLocation.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/NSInvocation+OCMAdditions.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/NSValue+OCMAdditions.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCObserverMockObject.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/NSMethodSignature+OCMAdditions.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMRealObjectForwarder.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMMacroState.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMArgAction.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMockObject.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMExpectationRecorder.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMBlockCaller.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMExceptionReturnValueProvider.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMIndirectReturnValueProvider.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMFunctions.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMStubRecorder.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMRecorder.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMInvocationExpectation.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCPartialMockObject.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMInvocationStub.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMPassByRefSetter.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMInvocationMatcher.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/NSObject+OCMAdditions.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCClassMockObject.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMBoxedReturnValueProvider.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMBlockArgCaller.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMReturnValueProvider.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCProtocolMockObject.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/NSMethodSignature+OCMAdditions.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMFunctionsPrivate.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/NSInvocation+OCMAdditions.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCObserverMockObject.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/NSValue+OCMAdditions.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMLocation.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMConstraint.h"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMVerifier.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMNotificationPoster.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMObserverRecorder.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/NSNotificationCenter+OCMAdditions.m"
"${CMAKE_SOURCE_DIR}/Pods/OCMock/Source/OCMock/OCMArg.h"
)
target_link_libraries(OCMock PUBLIC "-framework Cocoa")
target_compile_options(OCMock PRIVATE -fno-objc-arc)
endfunction()
function(ImportCocoaPodsLibrary library_name source_directory)
set_source_files_properties(${ARGN} PROPERTIES GENERATED True)
add_library("${library_name}" STATIC ${ARGN})
add_dependencies("${library_name}" "${PROJECT_NAME}")
target_include_directories("${library_name}" PUBLIC
"${source_directory}"
"${CMAKE_SOURCE_DIR}/Pods/Headers/Public"
)
target_compile_options("${library_name}" PUBLIC
-Wno-deprecated -fmodules -fcxx-modules -fobjc-arc
-mmacosx-version-min=${MACOSX_VERSION_MIN}
)
if(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo" OR CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_options("${library_name}" PRIVATE -g3)
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_options("${library_name}" PRIVATE -O0)
else()
target_compile_options("${library_name}" PRIVATE -O3)
endif()
endfunction()
main()

View File

@@ -1,12 +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>
<!-- Minimal Configuration -->
<key>ClientMode</key>
<integer>1</integer>
<!-- For documentation of other keys, see the following URL:
https://github.com/google/santa/wiki/Configuration-Keys -->
</dict>
</plist>

View File

@@ -39,6 +39,12 @@ GUI_USER=$(/usr/bin/stat -f '%u' /dev/console)
mkdir -p /usr/local/bin
/bin/ln -s /Library/Extensions/santa-driver.kext/Contents/MacOS/santactl /usr/local/bin
if [ ! -d /var/db/santa ] ; then
mkdir /var/db/santa
fi
cp ${SOURCE}/conf/com.google.santa.example.mobileconfig /var/db/santa
/bin/cp ${SOURCE}/conf/com.google.santad.plist /Library/LaunchDaemons
/bin/cp ${SOURCE}/conf/com.google.santagui.plist /Library/LaunchAgents
/bin/cp ${SOURCE}/conf/com.google.santa.asl.conf /etc/asl/

View File

@@ -6,6 +6,15 @@
[ "$EUID" != 0 ] && printf "%s\n" "This requires running as root/sudo." && exit 1
if [[ -d "binaries" ]]; then
SOURCE="."
elif [[ -d "../binaries" ]]; then
SOURCE=".."
else
echo "Can't find binaries, run install.sh from inside the conf directory" 1>&2
exit 1
fi
/bin/launchctl remove com.google.santad
sleep 1
/sbin/kextunload -b com.google.santa-driver >/dev/null 2>&1
@@ -21,6 +30,7 @@ user=$(/usr/bin/stat -f '%u' /dev/console)
/bin/rm -f /private/etc/asl/com.google.santa.asl.conf
/bin/rm -f /private/etc/newsyslog.d/com.google.santa.newsyslog.conf
/bin/rm -f /usr/local/bin/santactl # just a symlink
#uncomment to remove the config file and all databases, log files
#/bin/rm -rf /var/db/santa
#/bin/rm -f /var/log/santa*

25
Fuzzing/CMakeLists.txt Normal file
View File

@@ -0,0 +1,25 @@
cmake_minimum_required(VERSION 3.10.0)
set(LIBFUZZER_PATH "${CMAKE_CURRENT_SOURCE_DIR}/libFuzzer/bin/libFuzzer.a")
function(ImportLibFuzzer)
add_custom_command(
OUTPUT "${LIBFUZZER_PATH}"
COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/libFuzzer/build.sh"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/libFuzzer/build.sh"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/libFuzzer"
COMMENT "Building libFuzzer..."
)
add_custom_target(libfuzzer_builder DEPENDS "${LIBFUZZER_PATH}")
endfunction()
function(main)
ImportLibFuzzer()
add_subdirectory(santacache)
add_subdirectory(santad)
add_subdirectory(santactl)
endfunction()
main()

4
Fuzzing/libFuzzer/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
bin
llvm-*.src
llvm-*.src.tar.xz

109
Fuzzing/libFuzzer/build.sh Executable file
View File

@@ -0,0 +1,109 @@
#!/usr/bin/env bash
LLVM_VERSION='5.0.1'
LLVM_COMPILERRT_TARBALL_NAME="llvm-${LLVM_VERSION}.src.tar.xz"
LLVM_COMPILERRT_SRC_FOLDER_NAME=`echo "${LLVM_COMPILERRT_TARBALL_NAME}" | cut -d '.' -f 1-4`
LLVM_COMPILERRT_TARBALL_URL="http://releases.llvm.org/${LLVM_VERSION}/${LLVM_COMPILERRT_TARBALL_NAME}"
LIBFUZZER_FOLDER="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
LOG_FILE=`mktemp`
main() {
echo "libFuzzer build script"
echo " > Checking dependencies..."
checkDependencies || return 1
echo " > Entering libFuzzer folder..."
cd "${LIBFUZZER_FOLDER}" > /dev/null 2>&1
if [ $? -ne 0 ] ; then
echo "Failed to enter the libFuzzer folder: ${LIBFUZZER_FOLDER}"
return 1
fi
if [ ! -f "${LLVM_COMPILERRT_TARBALL_NAME}" ] ; then
echo " > Downloading the LLVM tarball..."
curl "${LLVM_COMPILERRT_TARBALL_URL}" -o "${LLVM_COMPILERRT_TARBALL_NAME}" > "${LOG_FILE}" 2>&1
if [ $? -ne 0 ] ; then
dumpLogFile "Failed to download the LLVM tarball"
return 1
fi
else
echo " > An existing LLVM tarball was found"
fi
if [ -d "${LLVM_COMPILERRT_SRC_FOLDER_NAME}" ] ; then
echo " > Deleting existing LLVM folder..."
rm -rf "${LLVM_COMPILERRT_SRC_FOLDER_NAME}" > "${LOG_FILE}" 2>&1
if [ $? -ne 0 ] ; then
dumpLogFile "Failed to delete the existing source folder"
return 1
fi
fi
echo " > Extracting the LLVM tarball..."
tar xf "${LLVM_COMPILERRT_TARBALL_NAME}" > "${LOG_FILE}" 2>&1
if [ $? -ne 0 ] ; then
rm "${LLVM_COMPILERRT_TARBALL_NAME}" "${LLVM_COMPILERRT_SRC_FOLDER_NAME}"
dumpLogFile "Failed to extract the LLVM tarball"
return 1
fi
if [ -d "bin" ] ; then
echo " > Deleting existing bin folder..."
rm -rf "bin" > "${LOG_FILE}" 2>&1
if [ $? -ne 0 ] ; then
dumpLogFile "Failed to delete the existing bin folder"
return 1
fi
fi
mkdir "bin" > "${LOG_FILE}" 2>&1
if [ $? -ne 0 ] ; then
dumpLogFile "Failed to create the bin folder"
return 1
fi
echo " > Building libFuzzer..."
( cd "bin" && "../${LLVM_COMPILERRT_SRC_FOLDER_NAME}/lib/Fuzzer/build.sh" ) > "${LOG_FILE}" 2>&1
if [ $? -ne 0 ] ; then
dumpLogFile "Failed to build the library"
return 1
fi
printf "\nFinished building libFuzzer\n"
rm "${LOG_FILE}"
return 0
}
checkDependencies() {
executable_list=( "clang++" "curl" "tar" )
for executable in "${executable_list[@]}" ; do
which "${executable}" > /dev/null 2>&1
if [ $? -ne 0 ] ; then
echo "The following program was not found: ${executable}"
return 1
fi
done
return 0
}
dumpLogFile() {
if [ $# -eq 1 ] ; then
local message="$1"
else
local message="An error has occurred"
fi
printf "${message}\n"
printf "Log file follows\n===\n"
cat "${LOG_FILE}"
printf "\n===\n"
rm "${LOG_FILE}"
}
main $@
exit $?

3
Fuzzing/santacache/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
santacache.dSYM
santacache

View File

@@ -0,0 +1,35 @@
cmake_minimum_required(VERSION 3.10.0)
project(santacache_fuzzer)
set(CMAKE_CXX_STANDARD 11)
function(main)
set(PROJECT_SOURCEFILES
src/main.cpp
)
add_executable("${PROJECT_NAME}" EXCLUDE_FROM_ALL ${PROJECT_SOURCEFILES})
add_dependencies("${PROJECT_NAME}" libfuzzer_builder)
target_link_libraries("${PROJECT_NAME}" PRIVATE "${LIBFUZZER_PATH}")
target_include_directories("${PROJECT_NAME}" PRIVATE
"${CMAKE_SOURCE_DIR}/Source/common"
"${CMAKE_SOURCE_DIR}/Source/santa-driver"
)
target_compile_options("${PROJECT_NAME}" PRIVATE
-g -O0 -Wno-deprecated-declarations
-fsanitize-coverage=trace-pc-guard
-mmacosx-version-min=${MACOSX_VERSION_MIN}
)
target_link_libraries("${PROJECT_NAME}" PRIVATE
-fsanitize=address -fno-omit-frame-pointer
-mno-omit-leaf-frame-pointer
)
AddFuzzTarget("${PROJECT_NAME}" 16 60 false)
endfunction()
main()

Binary file not shown.

View File

@@ -0,0 +1,41 @@
/// Copyright 2018 Google Inc. All rights reserved.
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
#include <SantaCache.h>
#include <iostream>
#include <cstdint>
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
static SantaCache<uint64_t, uint64_t> decision_cache(5000, 2);
std::uint64_t fields[2] = {};
if (size > 16) {
std::cout << "Invalid size! Start with -max_len=16\n";
return 1;
}
std::memcpy(fields, data, size);
decision_cache.set(fields[0], fields[1]);
auto returned_value = decision_cache.get(fields[0]);
if (returned_value != fields[1]) {
std::cout << fields[0] << ", " << fields[1] << " -> " << returned_value << "\n";
return 1;
}
return 0;
}

View File

@@ -0,0 +1,61 @@
cmake_minimum_required(VERSION 3.10.0)
project(santactl_fuzzer)
set(CMAKE_CXX_STANDARD 11)
function(main)
set(PROJECT_SOURCEFILES
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncRuleDownload.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncConstants.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncStage.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncState.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTRule.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTLogging.m"
src/main.mm
)
add_executable("${PROJECT_NAME}" EXCLUDE_FROM_ALL ${PROJECT_SOURCEFILES})
target_compile_options("${PROJECT_NAME}" PRIVATE
-fobjc-arc -Wno-everything -fmodules -fcxx-modules
-mmacosx-version-min=${MACOSX_VERSION_MIN}
)
target_compile_definitions("${PROJECT_NAME}" PRIVATE
COCOAPODS=1
)
target_include_directories("${PROJECT_NAME}" PRIVATE
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync"
"${CMAKE_SOURCE_DIR}/Source/common"
"${CMAKE_SOURCE_DIR}/Source/santad"
)
target_link_libraries("${PROJECT_NAME}" PRIVATE
MOLCertificate MOLCodesignChecker
MOLAuthenticatingURLSession FMDB MOLFCMClient
)
#
# Add libfuzzer
#
add_dependencies("${PROJECT_NAME}" libfuzzer_builder)
target_link_libraries("${PROJECT_NAME}" PRIVATE "${LIBFUZZER_PATH}")
target_compile_options("${PROJECT_NAME}" PRIVATE
-g -O0 -Wno-deprecated-declarations
-fsanitize-coverage=trace-pc-guard
)
target_link_libraries("${PROJECT_NAME}" PRIVATE
-fsanitize=address -fno-omit-frame-pointer
-mno-omit-leaf-frame-pointer
)
AddFuzzTarget("${PROJECT_NAME}" 428 60 false)
endfunction()
main()

View File

@@ -0,0 +1,16 @@
{
"rules": [
{
"rule_type": "BINARY",
"policy": "BLACKLIST",
"sha256": "2dc104631939b4bdf5d6bccab76e166e37fe5e1605340cf68dab919df58b8eda",
"custom_msg": "blacklist firefox"
},
{
"rule_type": "CERTIFICATE",
"policy": "BLACKLIST",
"sha256": "e7726cf87cba9e25139465df5bd1557c8a8feed5c7dd338342d8da0959b63c8d",
"custom_msg": "blacklist dash app certificate"
}
]
}

View File

@@ -0,0 +1,62 @@
/// Copyright 2018 Google Inc. All rights reserved.
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
#include <iostream>
#include <cstdint>
#include <vector>
#include <SNTCommandSyncRuleDownload.h>
#include <SNTCommandSyncState.h>
#include <SNTCommandSyncConstants.h>
#include <SNTRule.h>
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
NSData *buffer = [NSData dataWithBytes:static_cast<const void *>(data) length:size];
if (!buffer) {
return 0;
}
NSError *error;
NSDictionary *response = [NSJSONSerialization JSONObjectWithData:buffer options:0 error:&error];
if (!response) {
return 0;
}
if (![response isKindOfClass:[NSDictionary class]]) {
return 0;
}
if (![response objectForKey:kRules]) {
return 0;
}
SNTCommandSyncState *state = [[SNTCommandSyncState alloc] init];
if (!state) {
return 0;
}
SNTCommandSyncRuleDownload *obj = [[SNTCommandSyncRuleDownload alloc] initWithState:state];
if (!obj) {
return 0;
}
for (NSDictionary *ruleDict in response[kRules]) {
SNTRule *rule = [obj ruleFromDictionary:ruleDict];
if (rule) {
std::cerr << "Rule: " << [[rule description] UTF8String] << "\n";
}
}
return 0;
}

View File

@@ -0,0 +1,109 @@
cmake_minimum_required(VERSION 3.10.0)
project(santad_fuzzer)
set(CMAKE_CXX_STANDARD 11)
function(main)
GenerateFuzzTarget(src/databaseRuleAddRules.mm 45 60 true)
GenerateFuzzTarget(src/checkCacheForVnodeID.mm 16 60 true)
GenerateFuzzTarget(src/databaseRemoveEventsWithIDs.mm 80 60 true)
endfunction()
function(GenerateFuzzTarget source_file data_size timeout run_as_root)
# Generate one new project for each source file in the 'src' folder. Copy
# the project source files and settings from santactl
set(PROJECT_SANTACTLSOURCEFILES
"${CMAKE_SOURCE_DIR}/Source/santactl/SNTCommand.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/SNTCommand.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/SNTCommandController.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/SNTCommandController.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Resources/santactl-Info.plist"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/SNTCommandBundleInfo.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/SNTCommandCheckCache.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/SNTCommandFileInfo.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/SNTCommandFlushCache.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/SNTCommandRule.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/SNTCommandStatus.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/SNTCommandVersion.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/NSData+Zlib.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/NSData+Zlib.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSync.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncConstants.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncConstants.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncEventUpload.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncEventUpload.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncLogUpload.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncLogUpload.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncManager.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncManager.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncPostflight.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncPostflight.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncPreflight.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncPreflight.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncRuleDownload.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncRuleDownload.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncStage.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncStage.m"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncState.h"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync/SNTCommandSyncState.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTConfigurator.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTFileInfo.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTRule.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTStoredEvent.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTSystemInfo.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTXPCControlInterface.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTXPCSyncdInterface.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTLogging.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTDropRootPrivs.m"
)
get_filename_component(target_name "${source_file}" NAME_WE)
set(target_name "santad_${target_name}_fuzzer")
add_executable("${target_name}" EXCLUDE_FROM_ALL ${source_file} ${PROJECT_SANTACTLSOURCEFILES})
target_compile_options("${target_name}" PRIVATE
-fobjc-arc -Wno-everything -fmodules -fcxx-modules
-mmacosx-version-min=${MACOSX_VERSION_MIN}
)
target_compile_definitions("${target_name}" PRIVATE
COCOAPODS=1
)
target_include_directories("${target_name}" PRIVATE
"${CMAKE_SOURCE_DIR}/Source/santactl"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync"
"${CMAKE_SOURCE_DIR}/Source/santad"
"${CMAKE_SOURCE_DIR}/Source/common"
)
target_link_libraries("${target_name}" PRIVATE
MOLCertificate MOLCodesignChecker
MOLAuthenticatingURLSession FMDB MOLFCMClient
MOLXPCConnection
)
#
# Add libfuzzer
#
add_dependencies("${target_name}" libfuzzer_builder)
target_link_libraries("${target_name}" PRIVATE "${LIBFUZZER_PATH}")
target_compile_options("${target_name}" PRIVATE
-g -O0 -Wno-deprecated-declarations
-fsanitize-coverage=trace-pc-guard
)
target_link_libraries("${target_name}" PRIVATE
-fsanitize=address -fno-omit-frame-pointer
-mno-omit-leaf-frame-pointer
)
AddFuzzTarget("${target_name}" ${data_size} ${timeout} ${run_as_root})
endfunction()
main()

View File

@@ -0,0 +1 @@
К'.p▒└G╗М┐║ЙSЮ╝и▌РУерЭxt1iАЫШ9ы*H╩4R"═©$-├Уww╙+Р╝╘[┼иу╧oС┬ОwRpЗя≤х°е

View File

@@ -0,0 +1,55 @@
/// Copyright 2018 Google Inc. All rights reserved.
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
#include <iostream>
#include <cstdint>
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTCommandController.h"
#import "SNTRule.h"
#import "SNTXPCControlInterface.h"
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
if (size > 16) {
std::cerr << "Invalid buffer size of " << size
<< " (should be <= 16)" << std::endl;
return 1;
}
santa_vnode_id_t vnodeID = {};
std::memcpy(&vnodeID, data, size);
MOLXPCConnection *daemonConn = [SNTXPCControlInterface configuredConnection];
daemonConn.invalidationHandler = ^{
printf("An error occurred communicating with the daemon, is it running?\n");
exit(1);
};
[daemonConn resume];
[[daemonConn remoteObjectProxy] checkCacheForVnodeID:vnodeID
withReply:^(santa_action_t action) {
if (action == ACTION_RESPOND_ALLOW) {
std::cerr << "File exists in [whitelist] kernel cache" << std::endl;;
} else if (action == ACTION_RESPOND_DENY) {
std::cerr << "File exists in [blacklist] kernel cache" << std::endl;;
} else if (action == ACTION_UNSET) {
std::cerr << "File does not exist in cache" << std::endl;;
}
}];
return 0;
}

View File

@@ -0,0 +1,51 @@
/// Copyright 2018 Google Inc. All rights reserved.
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
#include <iostream>
#include <cstdint>
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTCommandController.h"
#import "SNTRule.h"
#import "SNTXPCControlInterface.h"
#pragma pack(push, 1)
#pragma pack(pop)
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
auto *eventId = reinterpret_cast<const std::uint64_t *>(data);
std::size_t eventIdCount = size / sizeof(std::uint64_t);
if (eventIdCount == 0) {
return 0;
}
MOLXPCConnection *daemonConn = [SNTXPCControlInterface configuredConnection];
daemonConn.invalidationHandler = ^{
printf("An error occurred communicating with the daemon, is it running?\n");
exit(1);
};
[daemonConn resume];
NSMutableSet *eventIds = [NSMutableSet setWithCapacity:eventIdCount];
for (std::size_t i = 0; i < eventIdCount; i++) {
auto id = [NSNumber numberWithInteger:eventId[i]];
[eventIds addObject:id];
}
[[daemonConn remoteObjectProxy] databaseRemoveEventsWithIDs:[eventIds allObjects]];
return 0;
}

View File

@@ -0,0 +1,73 @@
/// Copyright 2018 Google Inc. All rights reserved.
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
#include <iostream>
#include <cstdint>
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTCommandController.h"
#import "SNTRule.h"
#import "SNTXPCControlInterface.h"
#pragma pack(push, 1)
struct InputData {
std::uint32_t cleanSlate;
std::uint32_t state;
std::uint32_t type;
char hash[33];
};
#pragma pack(pop)
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
if (size > sizeof(InputData)) {
std::cerr << "Invalid buffer size of " << size
<< " (should be <= " << sizeof(InputData)
<< ")" << std::endl;
return 1;
}
InputData input_data = {};
std::memcpy(&input_data, data, size);
SNTRule *newRule = [[SNTRule alloc] init];
newRule.state = (SNTRuleState) input_data.state;
newRule.type = (SNTRuleType) input_data.type;
newRule.shasum = @(input_data.hash);
newRule.customMsg = @"";
MOLXPCConnection *daemonConn = [SNTXPCControlInterface configuredConnection];
daemonConn.invalidationHandler = ^{
printf("An error occurred communicating with the daemon, is it running?\n");
exit(1);
};
[daemonConn resume];
[[daemonConn remoteObjectProxy] databaseRuleAddRules:@[newRule]
cleanSlate:NO
reply:^(NSError *error) {
if (!error) {
if (newRule.state == SNTRuleStateRemove) {
printf("Removed rule for SHA-256: %s.\n", [newRule.shasum UTF8String]);
} else {
printf("Added rule for SHA-256: %s.\n", [newRule.shasum UTF8String]);
}
}
}];
return 0;
}

View File

@@ -4,12 +4,12 @@ PODS:
- FMDB/standard (2.7.2)
- MOLAuthenticatingURLSession (2.4):
- MOLCertificate (~> 1.8)
- MOLCertificate (1.8)
- MOLCertificate (1.9)
- MOLCodesignChecker (1.10):
- MOLCertificate (~> 1.8)
- MOLFCMClient (1.7):
- MOLAuthenticatingURLSession (~> 2.4)
- MOLXPCConnection (1.1):
- MOLXPCConnection (1.2):
- MOLCodesignChecker (~> 1.9)
- OCMock (3.4.1)
@@ -35,10 +35,10 @@ SPEC REPOS:
SPEC CHECKSUMS:
FMDB: 6198a90e7b6900cfc046e6bc0ef6ebb7be9236aa
MOLAuthenticatingURLSession: c238aa1c9a7b1077eb39a6f40204bfe76a7d204e
MOLCertificate: c999513316d511c69f290fbf313dfe8dca4ad592
MOLCertificate: e9e88a396c57032cab847f51a46e20c730cd752a
MOLCodesignChecker: b0d5db9d2f9bd94e0fd093891a5d40e5ad77cbc0
MOLFCMClient: ee45348909351f232e2759c580329072ae7e02d4
MOLXPCConnection: de9d5535928f59766a768384e411077b83ec2f9c
MOLXPCConnection: c27af5cb1c43b18319698b0e568a8ddc2fc1e306
OCMock: 2cd0716969bab32a2283ff3a46fd26a8c8b4c5e3
PODFILE CHECKSUM: ddca043a7ace9ec600c108621c56d13a50d17236

View File

@@ -124,7 +124,7 @@ A tool like Santa doesn't really lend itself to screenshots, so here's a video i
<img src="https://zippy.gfycat.com/MadFatalAmphiuma.gif" alt="Santa Block Video" />
</p>
Building
Building with Xcode
========
```sh
@@ -144,6 +144,27 @@ and for security-reasons parts of Santa will not operate properly if not signed.
For more details on building see the [building.md](https://github.com/google/santa/blob/master/Docs/development/building.md) document.
Building with CMake
========
### General steps
1. Install Xcode and the command line tools
2. Install CMake using homebrew
3. Clone the santa source code repository
4. Set the signing key
5. Create a build folder and configure the project
6. Run make
Example
git clone https://github.com/google/santa.git
mkdir build
cd build
export CODESIGN_IDENTITY=XXX
cmake ../santa
make -j `sysctl -n hw.ncpu`
The CODESIGN_IDENTITY parameter can also be passed directly to CMake: cmake -DCODESIGN_IDENTITY=XXX /path/to/source/code
Kext Signing
============
Kernel extensions on macOS 10.9 and later must be signed using an Apple-provided

View File

@@ -185,6 +185,11 @@
C7FB56F71DBFB480004E14EF /* SNTXPCSyncdInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = C7FB56F51DBFB480004E14EF /* SNTXPCSyncdInterface.m */; };
C7FB57001DBFC213004E14EF /* SNTSyncdQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = C7FB56FF1DBFC213004E14EF /* SNTSyncdQueue.m */; };
D1761D2DAE8C790F29AFE6C9 /* libPods-LogicTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7D949AA996AEAC326A4F6596 /* libPods-LogicTests.a */; };
D221001320AB35FB003C65C2 /* SNTXPCUnprivilegedControlInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = D221001020AB35F3003C65C2 /* SNTXPCUnprivilegedControlInterface.m */; };
D221001420AB3609003C65C2 /* SNTXPCUnprivilegedControlInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = D221001020AB35F3003C65C2 /* SNTXPCUnprivilegedControlInterface.m */; };
D221001520AB360A003C65C2 /* SNTXPCUnprivilegedControlInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = D221001020AB35F3003C65C2 /* SNTXPCUnprivilegedControlInterface.m */; };
D221001620AB360A003C65C2 /* SNTXPCUnprivilegedControlInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = D221001020AB35F3003C65C2 /* SNTXPCUnprivilegedControlInterface.m */; };
D221001720AB360B003C65C2 /* SNTXPCUnprivilegedControlInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = D221001020AB35F3003C65C2 /* SNTXPCUnprivilegedControlInterface.m */; };
D6D356C5BC8709C2E355C113 /* libPods-santactl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E3B4B2438711ACD7D560014 /* libPods-santactl.a */; };
/* End PBXBuildFile section */
@@ -450,6 +455,8 @@
C7FB56F51DBFB480004E14EF /* SNTXPCSyncdInterface.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTXPCSyncdInterface.m; sourceTree = "<group>"; };
C7FB56FE1DBFC213004E14EF /* SNTSyncdQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNTSyncdQueue.h; sourceTree = "<group>"; };
C7FB56FF1DBFC213004E14EF /* SNTSyncdQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNTSyncdQueue.m; sourceTree = "<group>"; };
D221000F20AB35F3003C65C2 /* SNTXPCUnprivilegedControlInterface.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SNTXPCUnprivilegedControlInterface.h; sourceTree = "<group>"; };
D221001020AB35F3003C65C2 /* SNTXPCUnprivilegedControlInterface.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SNTXPCUnprivilegedControlInterface.m; sourceTree = "<group>"; };
D7DEE68F05C49966396A2F10 /* Pods-santad-santabs.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-santad-santabs.release.xcconfig"; path = "Pods/Target Support Files/Pods-santad-santabs/Pods-santad-santabs.release.xcconfig"; sourceTree = "<group>"; };
D9B2D7095028D87E12E63EF7 /* Pods-santad-santabs.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-santad-santabs.debug.xcconfig"; path = "Pods/Target Support Files/Pods-santad-santabs/Pods-santad-santabs.debug.xcconfig"; sourceTree = "<group>"; };
DF5FE88E12AB307864A53CE7 /* Pods-santactl.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-santactl.release.xcconfig"; path = "Pods/Target Support Files/Pods-santactl/Pods-santactl.release.xcconfig"; sourceTree = "<group>"; };
@@ -745,6 +752,8 @@
0DCD604E19115A06006B445C /* SNTXPCNotifierInterface.m */,
C7FB56F41DBFB480004E14EF /* SNTXPCSyncdInterface.h */,
C7FB56F51DBFB480004E14EF /* SNTXPCSyncdInterface.m */,
D221000F20AB35F3003C65C2 /* SNTXPCUnprivilegedControlInterface.h */,
D221001020AB35F3003C65C2 /* SNTXPCUnprivilegedControlInterface.m */,
);
path = common;
sourceTree = "<group>";
@@ -1375,6 +1384,7 @@
0DD0D492194F9BEF005F27EB /* SNTLogging.m in Sources */,
0DE71A761B95F7F900518526 /* SNTCachedDecision.m in Sources */,
0DCD605919115E5A006B445C /* SNTXPCNotifierInterface.m in Sources */,
D221001720AB360B003C65C2 /* SNTXPCUnprivilegedControlInterface.m in Sources */,
0DE50F691912B0CD007B2B0C /* SNTRule.m in Sources */,
0D202D1B1CDD465400A88F16 /* SNTCommandSyncState.m in Sources */,
C73A4B9A1DC10753007B6789 /* SNTSyncdQueue.m in Sources */,
@@ -1403,6 +1413,7 @@
0D10BE871A0AABD600C0C944 /* SNTDropRootPrivs.m in Sources */,
0DE4C8A618FF3B1700466D04 /* SNTCommandFlushCache.m in Sources */,
4092327A1A51B66400A04527 /* SNTCommandRule.m in Sources */,
D221001420AB3609003C65C2 /* SNTXPCUnprivilegedControlInterface.m in Sources */,
C76614EC1D142D3C00D150C1 /* SNTCommandCheckCache.m in Sources */,
0D416401191974F1006A356A /* SNTCommandSyncState.m in Sources */,
0DC5D871192160180078A5C0 /* SNTCommandSyncLogUpload.m in Sources */,
@@ -1429,6 +1440,7 @@
0D89310F1C931986002E8D74 /* SNTRule.m in Sources */,
0DCD605119115A06006B445C /* SNTXPCNotifierInterface.m in Sources */,
0DB77FD91CCE824A004DF060 /* SNTBlockMessage.m in Sources */,
D221001620AB360A003C65C2 /* SNTXPCUnprivilegedControlInterface.m in Sources */,
0D827E6519DF392E006EC811 /* SNTConfigurator.m in Sources */,
0D89310E1C931979002E8D74 /* SNTXPCControlInterface.m in Sources */,
0D385DF2180DE51600418BC6 /* SNTMessageWindowController.m in Sources */,
@@ -1467,6 +1479,7 @@
0DB8ACC1185662DC00FEF9C7 /* SNTApplication.m in Sources */,
0D9A7F421759330500035EB5 /* main.m in Sources */,
0DA73C9F1934F8100056D7C4 /* SNTLogging.m in Sources */,
D221001320AB35FB003C65C2 /* SNTXPCUnprivilegedControlInterface.m in Sources */,
C7C721B11E23FF300051FAA6 /* SNTXPCBundleServiceInterface.m in Sources */,
0DE71A751B95F7F900518526 /* SNTCachedDecision.m in Sources */,
C7FB56F61DBFB480004E14EF /* SNTXPCSyncdInterface.m in Sources */,
@@ -1497,6 +1510,7 @@
C7C721B41E24042B0051FAA6 /* SNTStoredEvent.m in Sources */,
C7C721B51E2408BE0051FAA6 /* SNTFileInfo.m in Sources */,
C7BBA67E1E54C7E200F1E6A8 /* SNTXPCNotifierInterface.m in Sources */,
D221001520AB360A003C65C2 /* SNTXPCUnprivilegedControlInterface.m in Sources */,
C7479F071E5374BF0054C1CF /* SNTXPCControlInterface.m in Sources */,
C7479F091E5374E50054C1CF /* SNTRule.m in Sources */,
C79A23581E23F7E80037AFA8 /* main.m in Sources */,

View File

@@ -0,0 +1,139 @@
cmake_minimum_required(VERSION 3.10.0)
project(Santa)
function(CompileXib output_file_path_variable input_file_path)
get_filename_component(input_file_name "${input_file_path}" NAME_WE)
set(output_file_path "${CMAKE_CURRENT_BINARY_DIR}/${input_file_name}.nib")
add_custom_command(
OUTPUT "${output_file_path}"
COMMAND ibtool --compile "${output_file_path}" "${input_file_path}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Compiling: ${input_file_path}"
)
set("${output_file_path_variable}" "${output_file_path}" PARENT_SCOPE)
endfunction()
# It is important to only use absolute file paths with actool
function(CompileAssets asset_file_list_variable)
set(asset_file_list
"${CMAKE_CURRENT_BINARY_DIR}/AppIcon.icns"
"${CMAKE_CURRENT_BINARY_DIR}/Assets.car"
)
add_custom_command(
OUTPUT ${asset_file_list}
COMMAND xcrun actool --output-format=human-readable-text --notices --warnings --errors --platform macosx --minimum-deployment-target ${MACOSX_VERSION_MIN} --target-device mac --app-icon AppIcon --output-partial-info-plist "${CMAKE_CURRENT_BINARY_DIR}/Assets.plist" --compile "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/Resources/Images.xcassets"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Packaging resources"
)
set("${asset_file_list_variable}" ${asset_file_list} PARENT_SCOPE)
endfunction()
function(main)
# Include all files to make IDEs happy
set(PROJECT_SOURCEFILES
SNTAboutWindowController.h
SNTAboutWindowController.m
SNTAccessibleTextField.h
SNTAccessibleTextField.m
SNTAppDelegate.h
SNTAppDelegate.m
SNTMessageWindow.h
SNTMessageWindow.m
SNTMessageWindowController.h
SNTMessageWindowController.m
SNTNotificationManager.h
SNTNotificationManager.m
main.m
# The "common" folder contains some of the files required to build this target
"${CMAKE_SOURCE_DIR}/Source/common/SNTConfigurator.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTXPCControlInterface.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTXPCUnprivilegedControlInterface.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTBlockMessage.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTRule.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTStoredEvent.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTSystemInfo.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTXPCBundleServiceInterface.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTXPCNotifierInterface.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTLogging.m"
)
set(PROJECT_XIBFILES
"${CMAKE_CURRENT_SOURCE_DIR}/Resources/AboutWindow.xib"
"${CMAKE_CURRENT_SOURCE_DIR}/Resources/MessageWindow.xib"
)
foreach(xib_file ${PROJECT_XIBFILES})
CompileXib(output_nib_file_path "${xib_file}")
list(APPEND PROJECT_RESOURCES "${output_nib_file_path}")
list(APPEND PROJECT_SOURCEFILES "${output_nib_file_path}")
endforeach()
CompileAssets(asset_file_list)
foreach(asset_file ${asset_file_list})
list(APPEND PROJECT_RESOURCES "${asset_file}")
list(APPEND PROJECT_SOURCEFILES "${asset_file}")
endforeach()
add_executable("${PROJECT_NAME}" MACOSX_BUNDLE ${PROJECT_SOURCEFILES})
target_link_libraries("${PROJECT_NAME}" PRIVATE -ObjC)
set_target_properties("${PROJECT_NAME}" PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER "com.google.SantaGUI"
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Resources/SantaGUI-Info.plist"
RESOURCE "${PROJECT_RESOURCES}"
)
target_link_libraries("${PROJECT_NAME}" PRIVATE
MOLCertificate MOLCodesignChecker MOLXPCConnection
"-framework Cocoa"
)
target_compile_options("${PROJECT_NAME}" PRIVATE
-fobjc-arc -Wno-everything -fmodules
-mmacosx-version-min=${MACOSX_VERSION_MIN}
)
if(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
target_compile_options("${PROJECT_NAME}" PRIVATE -g3)
endif()
target_compile_definitions("${PROJECT_NAME}" PRIVATE
COCOAPODS=1
SANTAGUI=1
)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_definitions("${PROJECT_NAME}" PRIVATE DEBUG=1)
else()
target_compile_definitions("${PROJECT_NAME}" PRIVATE NDEBUG=1)
endif()
target_include_directories("${PROJECT_NAME}" PRIVATE
"${CMAKE_SOURCE_DIR}/Source/SantaGUI"
"${CMAKE_SOURCE_DIR}/Source/common"
"${CMAKE_SOURCE_DIR}/Source/santad"
)
add_custom_command(TARGET "${PROJECT_NAME}" POST_BUILD
COMMAND codesign --force --verify --verbose --sign "${CODESIGN_IDENTITY}" "${CMAKE_BINARY_DIR}/Source/SantaGUI/Santa.app"
COMMENT "Signing ${PROJECT_NAME} with the following identity: ${CODESIGN_IDENTITY}"
)
# Ignore errors about the missing RESOURCE destination missing; this is a cmake bug
install(TARGETS "${PROJECT_NAME}" BUNDLE DESTINATION "/Applications")
endfunction()
main()

View File

@@ -9,20 +9,24 @@
<key>NSHumanReadableCopyright</key>
<string>Google, Inc.</string>
<key>CFBundleIdentifier</key>
<string>com.google.${PRODUCT_NAME:rfc1034identifier}GUI</string>
<string>com.google.SantaGUI</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<string>Santa</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<string>Santa</string>
<key>CFBundleVersion</key>
<string>TO.BE.FILLED</string>
<string>${SANTA_VERSION}</string>
<key>CFBundleShortVersionString</key>
<string>TO.BE.FILLED</string>
<string>${SANTA_VERSION}</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<string>${MACOSX_VERSION_MIN}</string>
<key>LSUIElement</key>
<true/>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>CFBundleIconFile</key>
<string>AppIcon</string>
<key>CFBundleIconName</key>
<string>AppIcon</string>
</dict>
</plist>

View File

@@ -79,7 +79,7 @@
// Create listener for return connection from daemon.
NSXPCListener *listener = [NSXPCListener anonymousListener];
self.daemonListener = [[MOLXPCConnection alloc] initServerWithListener:listener];
self.daemonListener.exportedInterface = [SNTXPCNotifierInterface notifierInterface];
self.daemonListener.privilegedInterface = [SNTXPCNotifierInterface notifierInterface];
self.daemonListener.exportedObject = self.notificationManager;
self.daemonListener.acceptedHandler = ^{
dispatch_semaphore_signal(sema);
@@ -116,7 +116,7 @@
// Create listener for return connection from the bundle service.
NSXPCListener *listener = [NSXPCListener anonymousListener];
self.bundleListener = [[MOLXPCConnection alloc] initServerWithListener:listener];
self.bundleListener.exportedInterface = [SNTXPCNotifierInterface bundleNotifierInterface];
self.bundleListener.privilegedInterface = [SNTXPCNotifierInterface bundleNotifierInterface];
self.bundleListener.exportedObject = self.notificationManager;
self.bundleListener.acceptedHandler = ^{
dispatch_semaphore_signal(sema);

View File

@@ -12,120 +12,56 @@
/// See the License for the specific language governing permissions and
/// limitations under the License.
#import <Foundation/Foundation.h>
#import <MOLCertificate/MOLCertificate.h>
#import "SNTCachedDecision.h"
#import "SNTCommonEnums.h"
#import "SNTKernelCommon.h"
#import "SNTXPCBundleServiceInterface.h"
@class SNTRule;
@class SNTStoredEvent;
@class MOLXPCConnection;
#import "SNTXPCUnprivilegedControlInterface.h"
///
/// Protocol implemented by santad and utilized by santactl
/// Protocol implemented by santad and utilized by santactl (privileged operations)
///
@protocol SNTDaemonControlXPC
@protocol SNTDaemonControlXPC <SNTUnprivilegedDaemonControlXPC>
///
/// Kernel ops
///
- (void)cacheCounts:(void (^)(uint64_t count))reply;
- (void)flushCache:(void (^)(BOOL))reply;
- (void)cacheBucketCount:(void (^)(NSArray *))reply;
- (void)checkCacheForVnodeID:(santa_vnode_id_t)vnodeID withReply:(void (^)(santa_action_t))reply;
- (void)driverConnectionEstablished:(void (^)(BOOL))reply;
///
/// Database ops
///
- (void)databaseRuleCounts:(void (^)(int64_t binary, int64_t certificate))reply;
- (void)databaseRuleAddRules:(NSArray *)rules
cleanSlate:(BOOL)cleanSlate
reply:(void (^)(NSError *error))reply;
- (void)databaseEventCount:(void (^)(int64_t count))reply;
- (void)databaseEventsPending:(void (^)(NSArray *events))reply;
- (void)databaseRemoveEventsWithIDs:(NSArray *)ids;
- (void)databaseRuleForBinarySHA256:(NSString *)binarySHA256
certificateSHA256:(NSString *)certificateSHA256
reply:(void (^)(SNTRule *))reply;
///
/// Decision ops
///
///
/// @param filePath A Path to the file, can be nil.
/// @param fileSHA256 The pre-calculated SHA256 hash for the file, can be nil. If nil the hash will
/// be calculated by this method from the filePath.
/// @param certificateSHA256 A SHA256 hash of the signing certificate, can be nil.
/// @note If fileInfo and signingCertificate are both passed in, the most specific rule will be
/// returned. Binary rules take precedence over cert rules.
///
- (void)decisionForFilePath:(NSString *)filePath
fileSHA256:(NSString *)fileSHA256
certificateSHA256:(NSString *)certificateSHA256
reply:(void (^)(SNTEventState))reply;
///
/// Config ops
///
- (void)watchdogInfo:(void (^)(uint64_t, uint64_t, double, double))reply;
- (void)clientMode:(void (^)(SNTClientMode))reply;
- (void)setClientMode:(SNTClientMode)mode reply:(void (^)(void))reply;
- (void)xsrfToken:(void (^)(NSString *))reply;
- (void)setXsrfToken:(NSString *)token reply:(void (^)(void))reply;
- (void)fullSyncLastSuccess:(void (^)(NSDate *))reply;
- (void)setFullSyncLastSuccess:(NSDate *)date reply:(void (^)(void))reply;
- (void)ruleSyncLastSuccess:(void (^)(NSDate *))reply;
- (void)setRuleSyncLastSuccess:(NSDate *)date reply:(void (^)(void))reply;
- (void)syncCleanRequired:(void (^)(BOOL))reply;
- (void)setSyncCleanRequired:(BOOL)cleanReqd reply:(void (^)(void))reply;
- (void)setWhitelistPathRegex:(NSString *)pattern reply:(void (^)(void))reply;
- (void)setBlacklistPathRegex:(NSString *)pattern reply:(void (^)(void))reply;
- (void)bundlesEnabled:(void (^)(BOOL))reply;
- (void)setBundlesEnabled:(BOOL)bundlesEnabled reply:(void (^)(void))reply;
///
/// GUI Ops
///
- (void)setNotificationListener:(NSXPCListenerEndpoint *)listener;
- (void)setBundleNotificationListener:(NSXPCListenerEndpoint *)listener;
///
/// Syncd Ops
///
- (void)setSyncdListener:(NSXPCListenerEndpoint *)listener;
- (void)pushNotifications:(void (^)(BOOL))reply;
- (void)postRuleSyncNotificationWithCustomMessage:(NSString *)message reply:(void (^)(void))reply;
///
/// Bundle Ops
///
- (void)hashBundleBinariesForEvent:(SNTStoredEvent *)event reply:(SNTBundleHashBlock)reply;
- (void)syncBundleEvent:(SNTStoredEvent *)event relatedEvents:(NSArray<SNTStoredEvent *> *)events;
@end
@interface SNTXPCControlInterface : NSObject
@interface SNTXPCControlInterface : SNTXPCUnprivilegedControlInterface
///
/// Returns the MachService ID for this service.
/// Internal method used to initialize the control interface
///
+ (NSString *)serviceId;
///
/// Returns an initialized NSXPCInterface for the SNTDaemonControlXPC protocol.
/// Ensures any methods that accept custom classes as arguments are set-up before returning
///
+ (NSXPCInterface *)controlInterface;
///
/// Retrieve a pre-configured MOLXPCConnection for communicating with santad.
/// Connections just needs any handlers set and then can be resumed and used.
///
+ (MOLXPCConnection *)configuredConnection;
+ (void)initializeControlInterface:(NSXPCInterface *)r;
@end

View File

@@ -25,8 +25,8 @@
return @"SantaXPCControl";
}
+ (NSXPCInterface *)controlInterface {
NSXPCInterface *r = [NSXPCInterface interfaceWithProtocol:@protocol(SNTDaemonControlXPC)];
+ (void)initializeControlInterface:(NSXPCInterface *)r {
[super initializeControlInterface:r];
[r setClasses:[NSSet setWithObjects:[NSArray class], [SNTStoredEvent class], nil]
forSelector:@selector(databaseEventsPending:)
@@ -37,16 +37,11 @@
forSelector:@selector(databaseRuleAddRules:cleanSlate:reply:)
argumentIndex:0
ofReply:NO];
}
[r setClasses:[NSSet setWithObjects:[NSArray class], [SNTStoredEvent class], nil]
forSelector:@selector(hashBundleBinariesForEvent:reply:)
argumentIndex:1
ofReply:YES];
[r setClasses:[NSSet setWithObjects:[NSArray class], [SNTStoredEvent class], nil]
forSelector:@selector(syncBundleEvent:relatedEvents:)
argumentIndex:1
ofReply:NO];
+ (NSXPCInterface *)controlInterface {
NSXPCInterface *r = [NSXPCInterface interfaceWithProtocol:@protocol(SNTDaemonControlXPC)];
[self initializeControlInterface:r];
return r;
}

View File

@@ -0,0 +1,119 @@
/// Copyright 2015 Google Inc. All rights reserved.
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
#import <Foundation/Foundation.h>
#import <MOLCertificate/MOLCertificate.h>
#import "SNTCachedDecision.h"
#import "SNTCommonEnums.h"
#import "SNTKernelCommon.h"
#import "SNTXPCBundleServiceInterface.h"
@class SNTRule;
@class SNTStoredEvent;
@class MOLXPCConnection;
///
/// Protocol implemented by santad and utilized by santactl (unprivileged operations)
///
@protocol SNTUnprivilegedDaemonControlXPC
///
/// Kernel ops
///
- (void)cacheCounts:(void (^)(uint64_t count))reply;
- (void)cacheBucketCount:(void (^)(NSArray *))reply;
- (void)checkCacheForVnodeID:(santa_vnode_id_t)vnodeID withReply:(void (^)(santa_action_t))reply;
- (void)driverConnectionEstablished:(void (^)(BOOL))reply;
///
/// Database ops
///
- (void)databaseRuleCounts:(void (^)(int64_t binary, int64_t certificate))reply;
- (void)databaseEventCount:(void (^)(int64_t count))reply;
///
/// Decision ops
///
///
/// @param filePath A Path to the file, can be nil.
/// @param fileSHA256 The pre-calculated SHA256 hash for the file, can be nil. If nil the hash will
/// be calculated by this method from the filePath.
/// @param certificateSHA256 A SHA256 hash of the signing certificate, can be nil.
/// @note If fileInfo and signingCertificate are both passed in, the most specific rule will be
/// returned. Binary rules take precedence over cert rules.
///
- (void)decisionForFilePath:(NSString *)filePath
fileSHA256:(NSString *)fileSHA256
certificateSHA256:(NSString *)certificateSHA256
reply:(void (^)(SNTEventState))reply;
///
/// Config ops
///
- (void)watchdogInfo:(void (^)(uint64_t, uint64_t, double, double))reply;
- (void)xsrfToken:(void (^)(NSString *))reply;
- (void)clientMode:(void (^)(SNTClientMode))reply;
- (void)fullSyncLastSuccess:(void (^)(NSDate *))reply;
- (void)ruleSyncLastSuccess:(void (^)(NSDate *))reply;
- (void)syncCleanRequired:(void (^)(BOOL))reply;
- (void)bundlesEnabled:(void (^)(BOOL))reply;
///
/// GUI Ops
///
- (void)setNotificationListener:(NSXPCListenerEndpoint *)listener;
- (void)setBundleNotificationListener:(NSXPCListenerEndpoint *)listener;
///
/// Syncd Ops
///
- (void)pushNotifications:(void (^)(BOOL))reply;
///
/// Bundle Ops
///
- (void)hashBundleBinariesForEvent:(SNTStoredEvent *)event reply:(SNTBundleHashBlock)reply;
- (void)syncBundleEvent:(SNTStoredEvent *)event relatedEvents:(NSArray<SNTStoredEvent *> *)events;
@end
@interface SNTXPCUnprivilegedControlInterface : NSObject
///
/// Returns the MachService ID for this service.
///
+ (NSString *)serviceId;
///
/// Returns an initialized NSXPCInterface for the SNTUnprivilegedDaemonControlXPC protocol.
/// Ensures any methods that accept custom classes as arguments are set-up before returning
///
+ (NSXPCInterface *)controlInterface;
///
/// Retrieve a pre-configured MOLXPCConnection for communicating with santad.
/// Connections just needs any handlers set and then can be resumed and used.
///
+ (MOLXPCConnection *)configuredConnection;
///
/// Internal method used to initialize the control interface
///
+ (void)initializeControlInterface:(NSXPCInterface *)r;
@end

View File

@@ -0,0 +1,54 @@
/// Copyright 2015 Google Inc. All rights reserved.
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
#import "SNTXPCUnprivilegedControlInterface.h"
#import <MOLXPCConnection/MOLXPCConnection.h>
#import "SNTRule.h"
#import "SNTStoredEvent.h"
@implementation SNTXPCUnprivilegedControlInterface
+ (NSString *)serviceId {
return @"SantaUnprivilegedXPCControl";
}
+ (void)initializeControlInterface:(NSXPCInterface *)r {
[r setClasses:[NSSet setWithObjects:[NSArray class], [SNTStoredEvent class], nil]
forSelector:@selector(hashBundleBinariesForEvent:reply:)
argumentIndex:1
ofReply:YES];
[r setClasses:[NSSet setWithObjects:[NSArray class], [SNTStoredEvent class], nil]
forSelector:@selector(syncBundleEvent:relatedEvents:)
argumentIndex:1
ofReply:NO];
}
+ (NSXPCInterface *)controlInterface {
NSXPCInterface *r = [NSXPCInterface interfaceWithProtocol:@protocol(SNTUnprivilegedDaemonControlXPC)];
[self initializeControlInterface:r];
return r;
}
+ (MOLXPCConnection *)configuredConnection {
MOLXPCConnection *c = [[MOLXPCConnection alloc] initClientWithName:[self serviceId]
privileged:YES];
c.remoteInterface = [self controlInterface];
return c;
}
@end

View File

@@ -0,0 +1,112 @@
cmake_minimum_required(VERSION 3.10.0)
project(santa-driver)
set(CMAKE_CXX_STANDARD 11)
function(main)
# Include all files to make IDEs happy
set(PROJECT_INFOPLIST "${CMAKE_CURRENT_SOURCE_DIR}/Resources/santa-driver-Info.plist")
set(PROJECT_SOURCEFILES
SantaCache.h
SantaDecisionManager.cc
SantaDecisionManager.h
SantaDriver.cc
SantaDriver.h
SantaDriverClient.cc
SantaDriverClient.h
main.c
"${PROJECT_INFOPLIST}"
)
add_library("${PROJECT_NAME}" MODULE ${PROJECT_SOURCEFILES})
set_target_properties("${PROJECT_NAME}" PROPERTIES
BUNDLE TRUE
BUNDLE_EXTENSION "kext"
MACOSX_BUNDLE_INFO_PLIST "${PROJECT_INFOPLIST}"
)
# As we have to include the executables in the same bundle, make sure
# we add them as dependencies
add_dependencies("${PROJECT_NAME}" santad santactl santabs)
target_compile_options("${PROJECT_NAME}" PRIVATE
-fmessage-length=0 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit=0
-nostdinc -fmodules -gmodules -fno-builtin -Wno-trigraphs -msoft-float -O0 -fno-common
-fapple-kext -fasm-blocks -fstrict-aliasing -MMD -MT dependencies
-mmacosx-version-min=${MACOSX_VERSION_MIN}
)
if(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
target_compile_options("${PROJECT_NAME}" PRIVATE -g3)
endif()
target_compile_options("${PROJECT_NAME}" PRIVATE
-Wnon-modular-include-in-framework-module -Werror=non-modular-include-in-framework-module
-Wno-missing-field-initializers -Wno-missing-prototypes -Werror=return-type -Wdocumentation
-Wunreachable-code -Werror=deprecated-objc-isa-usage -Werror=objc-root-class -Wno-missing-braces
-Wparentheses -Wswitch -Wunused-function -Wno-unused-label -Wno-unused-parameter
-Wunused-variable -Wunused-value -Wempty-body -Wuninitialized -Wconditional-uninitialized
-Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wconstant-conversion
-Wint-conversion -Wbool-conversion -Wenum-conversion -Wno-float-conversion
-Wnon-literal-null-conversion -Wobjc-literal-conversion -Wshorten-64-to-32 -Wpointer-sign
-Wno-newline-eof -Wdeprecated-declarations -Wno-sign-conversion -Winfinite-recursion -Wcomma
-Wblock-capture-autoreleasing -Wstrict-prototypes -Wunguarded-availability
)
target_compile_definitions("${PROJECT_NAME}" PRIVATE
KERNEL
KERNEL_PRIVATE
DRIVER_PRIVATE
APPLE
NeXT
CMAKE
-DSANTA_VERSION="${SANTA_VERSION}"
)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_definitions("${PROJECT_NAME}" PRIVATE DEBUG)
else()
target_compile_definitions("${PROJECT_NAME}" PRIVATE NDEBUG)
endif()
target_include_directories("${PROJECT_NAME}" SYSTEM PRIVATE
"${XCODE_ROOT_FOLDER}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX${MACOSX_SDK_VERSION}.sdk/System/Library/Frameworks/Kernel.framework/PrivateHeaders"
"${XCODE_ROOT_FOLDER}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX${MACOSX_SDK_VERSION}.sdk/System/Library/Frameworks/Kernel.framework/Headers"
)
target_include_directories("${PROJECT_NAME}" PRIVATE
"${CMAKE_SOURCE_DIR}/Source/santa-driver"
"${CMAKE_SOURCE_DIR}/Source/common"
)
target_link_libraries("${PROJECT_NAME}" PRIVATE
-Xlinker -export_dynamic
-Xlinker -no_deduplicate
-Xlinker -kext
-nostdlib -lkmodc++ -lkmod -lcc_kext
)
add_custom_command(TARGET "${PROJECT_NAME}" POST_BUILD
# Copy santad and santactl
COMMAND "${CMAKE_COMMAND}" -E copy $<TARGET_FILE:santad> "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.kext/Contents/MacOS"
COMMAND "${CMAKE_COMMAND}" -E copy $<TARGET_FILE:santactl> "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.kext/Contents/MacOS"
# Copy the the santabs service
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_BINARY_DIR}/Source/santabs/santabs.xpc" "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.kext/Contents/XPCServices/santabs.xpc"
# Sign everything
COMMAND codesign --force --verify --verbose --sign "${CODESIGN_IDENTITY}" "${CMAKE_BINARY_DIR}/Source/santa-driver/santa-driver.kext"
COMMENT "Building and signing santa-driver.kext"
)
install(TARGETS "${PROJECT_NAME}" LIBRARY DESTINATION "/Library/Extensions")
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink /Library/Extensions/santa-driver.kext/Contents/MacOS/santactl /usr/local/bin/santactl)")
endfunction()
main()

View File

@@ -9,15 +9,15 @@
<key>NSHumanReadableCopyright</key>
<string>Google, Inc.</string>
<key>CFBundleIdentifier</key>
<string>com.google.${PRODUCT_NAME:rfc1034identifier}</string>
<string>com.google.santa-driver</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<string>santa-driver</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<string>santa-driver</string>
<key>CFBundleVersion</key>
<string>TO.BE.FILLED</string>
<string>${SANTA_VERSION}</string>
<key>CFBundleShortVersionString</key>
<string>TO.BE.FILLED</string>
<string>${SANTA_VERSION}</string>
<key>IOKitPersonalities</key>
<dict>
<key>SantaDriver</key>

View File

@@ -115,8 +115,8 @@ template<typename KeyT, typename ValueT> class SantaCache {
@note If the cache is full when this is called, this will
empty the cache before inserting the new value.
@param key, The key.
@param value, The value with parameterized type.
@param key The key.
@param value The value with parameterized type.
@return true if the value was set.
*/
@@ -130,9 +130,9 @@ template<typename KeyT, typename ValueT> class SantaCache {
@note If the cache is full when this is called, this will
empty the cache before inserting the new value.
@param key, The key.
@param value, The value with parameterized type.
@param previous_value, the new value will only be set if this
@param key The key.
@param value The value with parameterized type.
@param previous_value the new value will only be set if this
parameter is equal to the existing value in the cache.
This allows set to become a CAS operation.
@@ -236,12 +236,12 @@ template<typename KeyT, typename ValueT> class SantaCache {
@note If the cache is full when this is called, this will
empty the cache before inserting the new value.
@param key, The key
@param value, The value with parameterized type
@param previous_value, If has_prev_value is true, the new value will only
@param key The key
@param value The value with parameterized type
@param previous_value If has_prev_value is true, the new value will only
be set if this parameter is equal to the existing value in the cache.
This allows set to become a CAS operation.
@param has_prev_value, Pass true if previous_value should be used.
@param has_prev_value Pass true if previous_value should be used.
@return true if the entry was set, false if it was not
*/

View File

@@ -308,13 +308,13 @@ class SantaDecisionManager : public OSObject {
/**
The kauth callback function for the Vnode scope
@param actor's credentials
@param data that was passed when the listener was registered
@param action that was requested
@param VFS context
@param Vnode being operated on
@param Parent Vnode. May be nullptr.
@param Pointer to an errno-style error.
@param credential actor's credentials
@param idata data that was passed when the listener was registered
@param action action that was requested
@param arg0 VFS context
@param arg1 Vnode being operated on
@param arg2 Parent Vnode. May be nullptr.
@param arg3 Pointer to an errno-style error.
*/
extern "C" int vnode_scope_callback(
kauth_cred_t credential,
@@ -328,13 +328,13 @@ extern "C" int vnode_scope_callback(
/**
The kauth callback function for the FileOp scope
@param actor's credentials
@param data that was passed when the listener was registered
@param action that was requested
@param depends on action, usually the vnode ref.
@param depends on action.
@param depends on action, usually 0.
@param depends on action, usually 0.
@param credential actor's credentials
@param idata data that was passed when the listener was registered
@param action action that was requested
@param arg0 depends on action, usually the vnode ref.
@param arg1 depends on action.
@param arg2 depends on action, usually 0.
@param arg3 depends on action, usually 0.
*/
extern "C" int fileop_scope_callback(
kauth_cred_t credential,

View File

@@ -0,0 +1,11 @@
#include <mach/mach_types.h>
extern kern_return_t _start(kmod_info_t *ki, void *data);
extern kern_return_t _stop(kmod_info_t *ki, void *data);
__attribute__((visibility("default"))) KMOD_EXPLICIT_DECL(com.google.santa-driver, SANTA_VERSION, _start, _stop)
__private_extern__ kmod_start_func_t *_realmain = 0;
__private_extern__ kmod_stop_func_t *_antimain = 0;
__private_extern__ int _kext_apple_cc = __APPLE_CC__ ;

View File

@@ -0,0 +1,68 @@
cmake_minimum_required(VERSION 3.10.0)
project(santabs)
function(main)
# Include all files to make IDEs happy
set(PROJECT_SOURCEFILES
SNTBundleService.h
SNTBundleService.m
main.m
Resources/santabs-Info.plist
# The "common" folder contains some of the files required to build this target
"${CMAKE_SOURCE_DIR}/Source/common/SNTFileInfo.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTStoredEvent.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTXPCBundleServiceInterface.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTXPCNotifierInterface.m"
)
add_executable("${PROJECT_NAME}" MACOSX_BUNDLE ${PROJECT_SOURCEFILES})
target_link_libraries("${PROJECT_NAME}" PRIVATE -ObjC)
set_target_properties("${PROJECT_NAME}" PROPERTIES
BUNDLE_EXTENSION "xpc"
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Resources/santabs-Info.plist"
)
target_link_libraries("${PROJECT_NAME}" PRIVATE
MOLCertificate MOLCodesignChecker
FMDB MOLXPCConnection
"-framework Cocoa"
)
target_compile_options("${PROJECT_NAME}" PRIVATE
-fobjc-arc -Wno-everything -fmodules
-mmacosx-version-min=${MACOSX_VERSION_MIN}
)
if(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
target_compile_options("${PROJECT_NAME}" PRIVATE -g3)
endif()
target_compile_definitions("${PROJECT_NAME}" PRIVATE
COCOAPODS=1
)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_definitions("${PROJECT_NAME}" PRIVATE DEBUG=1)
else()
target_compile_definitions("${PROJECT_NAME}" PRIVATE NDEBUG=1)
endif()
target_include_directories("${PROJECT_NAME}" PRIVATE
"${CMAKE_SOURCE_DIR}/Source/santabs"
"${CMAKE_SOURCE_DIR}/Source/common"
)
add_custom_command(TARGET "${PROJECT_NAME}" POST_BUILD
COMMAND codesign --force --verify --verbose --sign "${CODESIGN_IDENTITY}" "${CMAKE_BINARY_DIR}/Source/santabs/santabs.xpc/Contents/MacOS/santabs"
COMMAND codesign --force --verify --verbose --sign "${CODESIGN_IDENTITY}" "${CMAKE_BINARY_DIR}/Source/santabs/santabs.xpc"
COMMENT "Signing ${PROJECT_NAME} with the following identity: ${CODESIGN_IDENTITY}"
)
endfunction()
main()

View File

@@ -7,21 +7,21 @@
<key>CFBundleDisplayName</key>
<string>santabs</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<string>santabs</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<string>com.google.santabs</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<string>santabs</string>
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<string>${SANTA_VERSION}</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<string>${SANTA_VERSION}</string>
<key>XPCService</key>
<dict>
<key>ServiceType</key>

View File

@@ -49,7 +49,7 @@
// Create listener for return connection from SantaGUI.
NSXPCListener *listener = [NSXPCListener anonymousListener];
self.listener = [[MOLXPCConnection alloc] initServerWithListener:listener];
self.listener.exportedInterface = [SNTXPCBundleServiceInterface bundleServiceInterface];
self.listener.unprivilegedInterface = self.listener.privilegedInterface = [SNTXPCBundleServiceInterface bundleServiceInterface];
self.listener.exportedObject = self;
self.listener.acceptedHandler = ^{
dispatch_semaphore_signal(sema);

View File

@@ -22,7 +22,7 @@
int main(int argc, const char *argv[]) {
MOLXPCConnection *c =
[[MOLXPCConnection alloc] initServerWithListener:[NSXPCListener serviceListener]];
c.exportedInterface = [SNTXPCBundleServiceInterface bundleServiceInterface];
c.privilegedInterface = c.unprivilegedInterface = [SNTXPCBundleServiceInterface bundleServiceInterface];
c.exportedObject = [[SNTBundleService alloc] init];
[c resume];
}

View File

@@ -0,0 +1,117 @@
cmake_minimum_required(VERSION 3.10.0)
project(santactl)
function(main)
# Include all files to make IDEs happy
set(PROJECT_SOURCEFILES
SNTCommand.h
SNTCommand.m
SNTCommandController.h
SNTCommandController.m
main.m
Resources/santactl-Info.plist
# Generic commands
Commands/SNTCommandBundleInfo.m
Commands/SNTCommandCheckCache.m
Commands/SNTCommandFileInfo.m
Commands/SNTCommandFlushCache.m
Commands/SNTCommandRule.m
Commands/SNTCommandStatus.m
Commands/SNTCommandVersion.m
Commands/SNTCommandCacheHistogram.m
# Sync server
Commands/sync/NSData+Zlib.h
Commands/sync/NSData+Zlib.m
Commands/sync/SNTCommandSync.m
Commands/sync/SNTCommandSyncConstants.h
Commands/sync/SNTCommandSyncConstants.m
Commands/sync/SNTCommandSyncEventUpload.h
Commands/sync/SNTCommandSyncEventUpload.m
Commands/sync/SNTCommandSyncLogUpload.h
Commands/sync/SNTCommandSyncLogUpload.m
Commands/sync/SNTCommandSyncManager.h
Commands/sync/SNTCommandSyncManager.m
Commands/sync/SNTCommandSyncPostflight.h
Commands/sync/SNTCommandSyncPostflight.m
Commands/sync/SNTCommandSyncPreflight.h
Commands/sync/SNTCommandSyncPreflight.m
Commands/sync/SNTCommandSyncRuleDownload.h
Commands/sync/SNTCommandSyncRuleDownload.m
Commands/sync/SNTCommandSyncStage.h
Commands/sync/SNTCommandSyncStage.m
Commands/sync/SNTCommandSyncState.h
Commands/sync/SNTCommandSyncState.m
# The "common" folder contains some of the files required to build this target
"${CMAKE_SOURCE_DIR}/Source/common/SNTConfigurator.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTFileInfo.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTRule.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTStoredEvent.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTSystemInfo.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTXPCControlInterface.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTXPCUnprivilegedControlInterface.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTXPCSyncdInterface.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTLogging.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTDropRootPrivs.m"
)
add_executable("${PROJECT_NAME}" ${PROJECT_SOURCEFILES})
target_link_libraries("${PROJECT_NAME}" PRIVATE -ObjC)
target_compile_options("${PROJECT_NAME}" PRIVATE
-fobjc-arc -Wno-everything -fmodules
-mmacosx-version-min=${MACOSX_VERSION_MIN}
)
if(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
target_compile_options("${PROJECT_NAME}" PRIVATE -g3)
endif()
target_compile_definitions("${PROJECT_NAME}" PRIVATE
COCOAPODS=1
)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_definitions("${PROJECT_NAME}" PRIVATE DEBUG=1)
else()
target_compile_definitions("${PROJECT_NAME}" PRIVATE NDEBUG=1)
endif()
target_include_directories("${PROJECT_NAME}" PRIVATE
"${CMAKE_SOURCE_DIR}/Source/santactl"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands"
"${CMAKE_SOURCE_DIR}/Source/santactl/Commands/sync"
"${CMAKE_SOURCE_DIR}/Source/santad"
"${CMAKE_SOURCE_DIR}/Source/common"
)
target_link_libraries("${PROJECT_NAME}" PRIVATE
MOLCertificate MOLCodesignChecker
MOLAuthenticatingURLSession FMDB MOLFCMClient
MOLXPCConnection
"-framework Cocoa"
)
add_custom_command(TARGET "${PROJECT_NAME}" POST_BUILD
COMMAND codesign --force --verify --verbose --sign "${CODESIGN_IDENTITY}" $<TARGET_FILE:${PROJECT_NAME}>
COMMENT "Signing ${PROJECT_NAME} with the following identity: ${CODESIGN_IDENTITY}"
)
endfunction()
main()

View File

@@ -37,7 +37,7 @@ REGISTER_COMMAND_NAME(@"sync")
#pragma mark SNTCommand protocol methods
+ (BOOL)requiresRoot {
return NO;
return YES;
}
+ (BOOL)requiresDaemonConn {
@@ -57,6 +57,9 @@ REGISTER_COMMAND_NAME(@"sync")
}
- (void)runWithArguments:(NSArray *)arguments {
// Connect to santad while we are root, so that we pass the XPC authentication
[self.daemonConn resume];
// Ensure we have no privileges
if (!DropRootPrivileges()) {
LOGE(@"Failed to drop root privileges. Exiting.");
@@ -68,7 +71,6 @@ REGISTER_COMMAND_NAME(@"sync")
exit(1);
}
[self.daemonConn resume];
BOOL daemon = [arguments containsObject:@"--daemon"];
self.syncManager = [[SNTCommandSyncManager alloc] initWithDaemonConnection:self.daemonConn
isDaemon:daemon];
@@ -91,7 +93,7 @@ REGISTER_COMMAND_NAME(@"sync")
// Create listener for return connection from daemon.
NSXPCListener *listener = [NSXPCListener anonymousListener];
self.listener = [[MOLXPCConnection alloc] initServerWithListener:listener];
self.listener.exportedInterface = [SNTXPCSyncdInterface syncdInterface];
self.listener.privilegedInterface = [SNTXPCSyncdInterface syncdInterface];
self.listener.exportedObject = self.syncManager;
self.listener.acceptedHandler = ^{
LOGD(@"santad <--> santactl connections established");

View File

@@ -15,6 +15,8 @@
#import <Foundation/Foundation.h>
#import "SNTCommandSyncStage.h"
#import "SNTRule.h"
@interface SNTCommandSyncRuleDownload : SNTCommandSyncStage
- (SNTRule *)ruleFromDictionary:(NSDictionary *)dict;
@end

View File

@@ -82,7 +82,11 @@
do {
NSDictionary *requestDict = cursor ? @{kCursor : cursor} : @{};
NSDictionary *response = [self performRequest:[self requestWithDictionary:requestDict]];
if (!response) return nil;
if (![response isKindOfClass:[NSDictionary class]]) {
return nil;
}
for (NSDictionary *ruleDict in response[kRules]) {
SNTRule *rule = [self ruleFromDictionary:ruleDict];
if (rule) [newRules addObject:rule];

View File

@@ -9,11 +9,11 @@
<key>CFBundleIdentifier</key>
<string>com.google.santactl</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<string>santactl</string>
<key>CFBundleShortVersionString</key>
<string>TO.BE.FILLED</string>
<string>${SANTA_VERSION}</string>
<key>CFBundleVersion</key>
<string>TO.BE.FILLED</string>
<string>${SANTA_VERSION}</string>
<key>CSFlags</key>
<string>kill</string>
</dict>

View File

@@ -0,0 +1,114 @@
cmake_minimum_required(VERSION 3.10.0)
project(santad)
function(main)
# Include all files to make IDEs happy
set(PROJECT_SOURCEFILES
SNTApplication.h
SNTApplication.m
SNTCachedDecision.h
SNTCachedDecision.m
SNTDaemonControlController.h
SNTDaemonControlController.m
SNTDatabaseController.h
SNTDatabaseController.m
SNTDriverManager.h
SNTDriverManager.m
SNTExecutionController.h
SNTExecutionController.m
SNTNotificationQueue.h
SNTNotificationQueue.m
SNTPolicyProcessor.h
SNTPolicyProcessor.m
SNTSyncdQueue.h
SNTSyncdQueue.m
DataLayer/SNTDatabaseTable.h
DataLayer/SNTDatabaseTable.m
DataLayer/SNTEventTable.h
DataLayer/SNTEventTable.m
DataLayer/SNTRuleTable.h
DataLayer/SNTRuleTable.m
Logs/SNTEventLog.h
Logs/SNTEventLog.m
Logs/SNTFileEventLog.h
Logs/SNTFileEventLog.m
Logs/SNTSyslogEventLog.h
Logs/SNTSyslogEventLog.m
main.m
Resources/santad-info.plist
# The "common" folder contains some of the files required to build this target
"${CMAKE_SOURCE_DIR}/Source/common/SNTBlockMessage.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTFileInfo.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTConfigurator.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTDropRootPrivs.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTRule.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTStoredEvent.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTSystemInfo.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTXPCBundleServiceInterface.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTXPCControlInterface.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTXPCUnprivilegedControlInterface.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTXPCNotifierInterface.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTXPCSyncdInterface.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTLogging.m"
)
add_executable("${PROJECT_NAME}" ${PROJECT_SOURCEFILES})
target_link_libraries("${PROJECT_NAME}" PRIVATE -ObjC)
target_link_libraries("${PROJECT_NAME}" PRIVATE
MOLCertificate MOLCodesignChecker
FMDB MOLXPCConnection
"-framework Cocoa"
)
target_compile_options("${PROJECT_NAME}" PRIVATE
-fobjc-arc -Wno-everything -fmodules
-mmacosx-version-min=${MACOSX_VERSION_MIN}
)
if(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
target_compile_options("${PROJECT_NAME}" PRIVATE -g3)
endif()
target_compile_definitions("${PROJECT_NAME}" PRIVATE
COCOAPODS=1
)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_definitions("${PROJECT_NAME}" PRIVATE DEBUG=1)
else()
target_compile_definitions("${PROJECT_NAME}" PRIVATE NDEBUG=1)
endif()
target_include_directories("${PROJECT_NAME}" PRIVATE
"${CMAKE_SOURCE_DIR}/Source/santad"
"${CMAKE_SOURCE_DIR}/Source/santad/DataLayer"
"${CMAKE_SOURCE_DIR}/Source/santad/Logs"
"${CMAKE_SOURCE_DIR}/Source/common"
)
add_custom_command(TARGET "${PROJECT_NAME}" POST_BUILD
COMMAND codesign --force --verify --verbose --sign "${CODESIGN_IDENTITY}" $<TARGET_FILE:${PROJECT_NAME}>
COMMENT "Signing ${PROJECT_NAME} with the following identity: ${CODESIGN_IDENTITY}"
)
endfunction()
main()

View File

@@ -9,10 +9,10 @@
<key>CFBundleIdentifier</key>
<string>com.google.santad</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<string>santad</string>
<key>CFBundleVersion</key>
<string>TO.BE.FILLED</string>
<string>${SANTA_VERSION}</string>
<key>CFBundleShortVersionString</key>
<string>TO.BE.FILLED</string>
<string>${SANTA_VERSION}</string>
</dict>
</plist>

View File

@@ -33,6 +33,7 @@
#import "SNTSyncdQueue.h"
#import "SNTSyslogEventLog.h"
#import "SNTXPCControlInterface.h"
#import "SNTXPCUnprivilegedControlInterface.h"
#import "SNTXPCNotifierInterface.h"
@interface SNTApplication ()
@@ -117,7 +118,8 @@
_controlConnection =
[[MOLXPCConnection alloc] initServerWithName:[SNTXPCControlInterface serviceId]];
_controlConnection.exportedInterface = [SNTXPCControlInterface controlInterface];
_controlConnection.privilegedInterface = [SNTXPCControlInterface controlInterface];
_controlConnection.unprivilegedInterface = [SNTXPCUnprivilegedControlInterface controlInterface];
_controlConnection.exportedObject = dc;
[_controlConnection resume];
@@ -261,10 +263,9 @@ void diskDisappearedCallback(DADiskRef disk, void *context) {
LOGI(@"Failed to fork");
self.syncdPID = 0;
} else if (self.syncdPID == 0) {
// Ensure we have no privileges
if (!DropRootPrivileges()) {
_exit(EPERM);
}
// The santactl executable will drop privileges just after the XPC
// connection has been estabilished; this is done this way so that
// the XPC authentication can occur
_exit(execl(kSantaCtlPath, kSantaCtlPath, "sync", "--daemon", "--syslog", NULL));
}
LOGI(@"santactl started with pid: %i", self.syncdPID);

21
Tests/CMakeLists.txt Normal file
View File

@@ -0,0 +1,21 @@
cmake_minimum_required(VERSION 3.10.0)
function(main)
file(GLOB test_list LIST_DIRECTORIES true "${CMAKE_CURRENT_SOURCE_DIR}/*")
foreach(test_path ${test_list})
if(NOT EXISTS "${test_path}/CMakeLists.txt")
continue()
endif()
if("${test_path}" STREQUAL "${CMAKE_SOURCE_DIR}/Tests/LogicTests")
message("Not adding LogicTests (not yet supported)")
continue()
endif()
message(STATUS "Adding test folder: ${test_path}")
add_subdirectory("${test_path}")
endforeach()
endfunction()
main()

View File

@@ -0,0 +1,31 @@
cmake_minimum_required(VERSION 3.10.0)
project(KernelTests)
set(CMAKE_CXX_STANDARD 11)
function(main)
# Include all files to make IDEs happy
set(PROJECT_SOURCEFILES
main.mm
)
add_executable("${PROJECT_NAME}" EXCLUDE_FROM_ALL ${PROJECT_SOURCEFILES})
AddTestTarget("${PROJECT_NAME}" true)
target_compile_options("${PROJECT_NAME}" PRIVATE
-fobjc-arc -Wno-everything -fmodules
-fcxx-modules -mmacosx-version-min=${MACOSX_VERSION_MIN}
)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_definitions("${PROJECT_NAME}" PRIVATE DEBUG=1)
else()
target_compile_definitions("${PROJECT_NAME}" PRIVATE NDEBUG=1)
endif()
target_include_directories("${PROJECT_NAME}" PRIVATE
"${CMAKE_SOURCE_DIR}/Source/common"
)
endfunction()
main()

View File

@@ -0,0 +1,55 @@
cmake_minimum_required(VERSION 3.10.0)
project(santa-driver-test)
function(main)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_GNU_EXTENSIONS OFF)
# Include all files to make IDEs happy
set(PROJECT_SOURCEFILES
main.mm
"${CMAKE_SOURCE_DIR}/Source/santad/SNTDriverManager.h"
"${CMAKE_SOURCE_DIR}/Source/santad/SNTDriverManager.m"
"${CMAKE_SOURCE_DIR}/Source/common/SNTLogging.m"
)
add_executable("${PROJECT_NAME}" EXCLUDE_FROM_ALL ${PROJECT_SOURCEFILES})
AddTestTarget("${PROJECT_NAME}" true)
target_link_libraries("${PROJECT_NAME}" PRIVATE
-ObjC "-framework Cocoa"
)
target_compile_options("${PROJECT_NAME}" PRIVATE
-fobjc-arc -Wno-everything -fmodules -fcxx-modules
-mmacosx-version-min=${MACOSX_VERSION_MIN}
)
if(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
target_compile_options("${PROJECT_NAME}" PRIVATE -g3)
endif()
target_compile_definitions("${PROJECT_NAME}" PRIVATE
COCOAPODS=1
)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_definitions("${PROJECT_NAME}" PRIVATE DEBUG=1)
else()
target_compile_definitions("${PROJECT_NAME}" PRIVATE NDEBUG=1)
endif()
target_include_directories("${PROJECT_NAME}" PRIVATE
"${CMAKE_SOURCE_DIR}/Source/santad"
"${CMAKE_SOURCE_DIR}/Source/common"
)
add_custom_command(TARGET "${PROJECT_NAME}" POST_BUILD
COMMAND codesign --force --verify --verbose --sign "${CODESIGN_IDENTITY}" $<TARGET_FILE:${PROJECT_NAME}>
COMMENT "Signing ${PROJECT_NAME} with the following identity: ${CODESIGN_IDENTITY}"
)
endfunction()
main()

View File

@@ -0,0 +1,70 @@
/// Copyright 2018 Google Inc. All rights reserved.
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
/*
This test will attempt to connect to the driver multiple times to make
sure that it doesn't cause crashes
*/
#import "SNTDriverManager.h"
#include <thread>
#include <mutex>
#include <condition_variable>
#include <iostream>
#include <vector>
#include <atomic>
std::mutex mutex;
std::condition_variable condVariable;
std::atomic_bool terminate(false);
void SignalHandler(int signalId) {
std::lock_guard<std::mutex> lock(mutex);
terminate = true;
condVariable.notify_one();
}
void Thread() {
while (!terminate) {
SNTDriverManager *driverManager = [[SNTDriverManager alloc] init];
if (driverManager != nullptr) {
std::cout << ".";
}
}
}
int main(int argc, const char *argv[]) {
signal(SIGINT, &SignalHandler);
std::vector<std::thread> thread_list;
for (auto i = 0U; i < 1U; i++) {
thread_list.emplace_back(Thread);
}
std::unique_lock<std::mutex> lock(mutex);
condVariable.wait(
lock,
[]{
return terminate.load();
}
);
for (auto &t : thread_list) {
t.join();
}
return 0;
}