diff --git a/lib/agent/aikido_types/init_data.go b/lib/agent/aikido_types/init_data.go index f784e5dd5..641b1c4c9 100644 --- a/lib/agent/aikido_types/init_data.go +++ b/lib/agent/aikido_types/init_data.go @@ -11,7 +11,7 @@ type MachineData struct { } type EnvironmentConfigData struct { - SocketPath string `json:"socket_path"` // '/run/aikido-{version}/aikido-{datetime}-{randint}.sock' + SocketPath string `json:"socket_path"` // '/var/run/aikido-{version}/aikido-{datetime}-{randint}.sock' PlatformName string `json:"platform_name"` // PHP platform name (fpm-fcgi, cli-server, ...) PlatformVersion string `json:"platform_version"` // PHP version Endpoint string `json:"endpoint,omitempty"` // default: 'https://guard.aikido.dev/' diff --git a/lib/agent/grpc/server.go b/lib/agent/grpc/server.go index 1ae6ac72c..743ae0308 100644 --- a/lib/agent/grpc/server.go +++ b/lib/agent/grpc/server.go @@ -101,7 +101,7 @@ func StartServer(lis net.Listener) { lis.Close() } -// Creates the /run/aikido-* folder if it does not exist, in order for the socket creation to succeed +// Creates the /var/run/aikido-* folder if it does not exist, in order for the socket creation to succeed // For now, this folder has 777 permissions as we don't know under which user the php requests will run under (apache, nginx, www-data, forge, ...) func createRunDirFolderIfNotExists() { runDirectory := filepath.Dir(globals.EnvironmentConfig.SocketPath) diff --git a/lib/agent/log/log.go b/lib/agent/log/log.go index b1fec892e..76841d900 100644 --- a/lib/agent/log/log.go +++ b/lib/agent/log/log.go @@ -6,6 +6,7 @@ import ( "log" "main/globals" "os" + "runtime" "sync/atomic" "time" ) @@ -113,20 +114,27 @@ func SetLogLevel(level string) error { return nil } +func GetAikidoLogDir() string { + if runtime.GOOS == "darwin" { + return fmt.Sprintf("/opt/homebrew/var/log/aikido-%s", globals.Version) + } + return fmt.Sprintf("/var/log/aikido-" + globals.Version) +} + func Init() { currentTime := time.Now() timeStr := currentTime.Format("20060102150405") - logFilePath := fmt.Sprintf("/var/log/aikido-%s/aikido-agent-%s-%d.log", globals.Version, timeStr, os.Getpid()) + logFilePath := fmt.Sprintf("%s/aikido-agent-%s-%d.log", GetAikidoLogDir(), timeStr, os.Getpid()) logFile, err := os.OpenFile(logFilePath, os.O_CREATE|os.O_WRONLY, 0666) - if err != nil { - log.Fatalf("Failed to open log file: %v", err) + if err == nil { + logger.SetOutput(logFile) } - - logger.SetOutput(logFile) } func Uninit() { - logger.SetOutput(os.Stdout) - logFile.Close() + if logFile != nil { + logger.SetOutput(os.Stdout) + logFile.Close() + } } diff --git a/lib/php-extension/Agent.cpp b/lib/php-extension/Agent.cpp index 01fa08b2c..1630bc9c5 100644 --- a/lib/php-extension/Agent.cpp +++ b/lib/php-extension/Agent.cpp @@ -16,8 +16,7 @@ std::string Agent::GetInitData() { } bool Agent::Init() { - std::string aikido_agent_lib_handle_path = - "/opt/aikido-" + std::string(PHP_AIKIDO_VERSION) + "/aikido-agent.so"; + std::string aikido_agent_lib_handle_path = AIKIDO_INSTALL_DIR "/aikido-agent.so"; this->libHandle = dlopen(aikido_agent_lib_handle_path.c_str(), RTLD_LAZY); if (!this->libHandle) { AIKIDO_LOG_ERROR("Error loading the Aikido Agent library from %s: %s!\n", diff --git a/lib/php-extension/GoWrappers.cpp b/lib/php-extension/GoWrappers.cpp index 9da3ea3b3..b9662fa25 100644 --- a/lib/php-extension/GoWrappers.cpp +++ b/lib/php-extension/GoWrappers.cpp @@ -1,11 +1,11 @@ #include "Includes.h" GoString GoCreateString(const std::string& s) { - return GoString{s.c_str(), s.length()}; + return GoString{s.c_str(), (ptrdiff_t)s.length()}; } GoSlice GoCreateSlice(const std::vector& v) { - return GoSlice{ (void*)v.data(), v.size(), v.capacity() }; + return GoSlice{ (void*)v.data(), (GoInt)v.size(), (GoInt)v.capacity() }; } /* Callback wrapper called by the RequestProcessor (GO) whenever it needs data from PHP (C++ extension). diff --git a/lib/php-extension/Log.cpp b/lib/php-extension/Log.cpp index d9cbae87f..533def58d 100644 --- a/lib/php-extension/Log.cpp +++ b/lib/php-extension/Log.cpp @@ -1,7 +1,7 @@ #include "Includes.h" void Log::Init() { - this->logFilePath = "/var/log/aikido-" + std::string(PHP_AIKIDO_VERSION) + "/aikido-extension-php-" + GetDateTime() + "-" + std::to_string(getpid()) + ".log"; + this->logFilePath = AIKIDO_LOG_DIR "/aikido-extension-php-" + GetDateTime() + "-" + std::to_string(getpid()) + ".log"; this->logFile = fopen(this->logFilePath.c_str(), "w"); AIKIDO_LOG_INFO("Opened log file %s!\n", this->logFilePath.c_str()); } diff --git a/lib/php-extension/RequestProcessor.cpp b/lib/php-extension/RequestProcessor.cpp index 80b2e455e..96a2139b0 100644 --- a/lib/php-extension/RequestProcessor.cpp +++ b/lib/php-extension/RequestProcessor.cpp @@ -97,7 +97,7 @@ bool RequestProcessor::Init() { return true; } - std::string requestProcessorLibPath = "/opt/aikido-" + std::string(PHP_AIKIDO_VERSION) + "/aikido-request-processor.so"; + std::string requestProcessorLibPath = AIKIDO_INSTALL_DIR "/aikido-request-processor.so"; this->libHandle = dlopen(requestProcessorLibPath.c_str(), RTLD_LAZY); if (!this->libHandle) { AIKIDO_LOG_ERROR("Error loading the Aikido Request Processor library from %s: %s!\n", requestProcessorLibPath.c_str(), dlerror()); diff --git a/lib/php-extension/Utils.cpp b/lib/php-extension/Utils.cpp index 1eae18b00..346d7aff9 100644 --- a/lib/php-extension/Utils.cpp +++ b/lib/php-extension/Utils.cpp @@ -28,7 +28,7 @@ std::string GetDateTime() { } std::string GenerateSocketPath() { - return "/run/aikido-" + std::string(PHP_AIKIDO_VERSION) + "/aikido-" + GetDateTime() + "-" + GetRandomNumber() + ".sock"; + return AIKIDO_RUN_DIR "/aikido-" + GetDateTime() + "-" + GetRandomNumber() + ".sock"; } const char* GetEventName(EVENT_ID event) { diff --git a/lib/php-extension/include/Environment.h b/lib/php-extension/include/Environment.h index 4db4c36f5..c686bd994 100644 --- a/lib/php-extension/include/Environment.h +++ b/lib/php-extension/include/Environment.h @@ -1,3 +1,13 @@ #pragma once +#ifdef __MACH__ +#define AIKIDO_INSTALL_DIR "/opt/homebrew/Cellar/aikido-php-firewall/" PHP_AIKIDO_VERSION "/aikido-" PHP_AIKIDO_VERSION +#define AIKIDO_LOG_DIR "/opt/homebrew/var/log/aikido-" PHP_AIKIDO_VERSION +#define AIKIDO_RUN_DIR "/opt/homebrew/var/run/aikido-" PHP_AIKIDO_VERSION +#else +#define AIKIDO_INSTALL_DIR "/opt/aikido-" PHP_AIKIDO_VERSION +#define AIKIDO_LOG_DIR "/opt/aikido-" PHP_AIKIDO_VERSION +#define AIKIDO_RUN_DIR "/var/run/aikido-" PHP_AIKIDO_VERSION +#endif + void LoadEnvironment(); diff --git a/lib/request-processor/aikido_types/config.go b/lib/request-processor/aikido_types/config.go index 5fccfcdc8..de19305e7 100644 --- a/lib/request-processor/aikido_types/config.go +++ b/lib/request-processor/aikido_types/config.go @@ -3,7 +3,7 @@ package aikido_types import "github.com/seancfoley/ipaddress-go/ipaddr" type EnvironmentConfigData struct { - SocketPath string `json:"socket_path"` // '/run/aikido-{version}/aikido-{datetime}-{randint}.sock' + SocketPath string `json:"socket_path"` // '/var/run/aikido-{version}/aikido-{datetime}-{randint}.sock' SAPI string `json:"sapi"` // '{php-sapi}' TrustProxy bool `json:"trust_proxy"` // default: true LocalhostAllowedByDefault bool `json:"localhost_allowed_by_default"` // default: true diff --git a/lib/request-processor/log/log.go b/lib/request-processor/log/log.go index 191189910..44990137f 100644 --- a/lib/request-processor/log/log.go +++ b/lib/request-processor/log/log.go @@ -6,6 +6,7 @@ import ( "log" "main/globals" "os" + "runtime" "time" ) @@ -129,6 +130,13 @@ func SetLogLevel(level string) error { return nil } +func GetAikidoLogDir() string { + if runtime.GOOS == "darwin" { + return fmt.Sprintf("/opt/homebrew/var/log/aikido-%s", globals.Version) + } + return fmt.Sprintf("/var/log/aikido-" + globals.Version) +} + func Init() { if globals.EnvironmentConfig.SAPI == "cli" { cliLogging = true @@ -136,7 +144,7 @@ func Init() { } currentTime := time.Now() timeStr := currentTime.Format("20060102150405") - logFilePath = fmt.Sprintf("/var/log/aikido-"+globals.Version+"/aikido-request-processor-%s-%d.log", timeStr, os.Getpid()) + logFilePath = fmt.Sprintf("%s/aikido-request-processor-%s-%d.log", GetAikidoLogDir(), timeStr, os.Getpid()) } func Uninit() { diff --git a/lib/request-processor/utils/utils.go b/lib/request-processor/utils/utils.go index d374e9cf3..d312d2f96 100644 --- a/lib/request-processor/utils/utils.go +++ b/lib/request-processor/utils/utils.go @@ -270,3 +270,10 @@ func GetArch() string { } panic(fmt.Sprintf("Running on unsupported architecture \"%s\"!", runtime.GOARCH)) } + +func GetAikidoInstallDir() string { + if runtime.GOOS == "darwin" { + return fmt.Sprintf("/opt/homebrew/Cellar/aikido-php-firewall/%s/aikido-%s-", globals.Version, globals.Version) + } + return fmt.Sprintf("/opt/aikido-" + globals.Version) +} diff --git a/lib/request-processor/vulnerabilities/zen-internals/zen_internals.go b/lib/request-processor/vulnerabilities/zen-internals/zen_internals.go index 747224a61..e9aa5aa78 100644 --- a/lib/request-processor/vulnerabilities/zen-internals/zen_internals.go +++ b/lib/request-processor/vulnerabilities/zen-internals/zen_internals.go @@ -19,7 +19,6 @@ int call_detect_sql_injection(detect_sql_injection_func func, const char* query, import "C" import ( "fmt" - "main/globals" "main/log" "main/utils" "unsafe" @@ -31,7 +30,7 @@ var ( ) func Init() bool { - zenInternalsLibPath := C.CString(fmt.Sprintf("/opt/aikido-%s/libzen_internals_%s-unknown-linux-gnu.so", globals.Version, utils.GetArch())) + zenInternalsLibPath := C.CString(fmt.Sprintf("%s/libzen_internals_%s-unknown-linux-gnu.so", utils.GetAikidoInstallDir(), utils.GetArch())) defer C.free(unsafe.Pointer(zenInternalsLibPath)) handle := C.dlopen(zenInternalsLibPath, C.RTLD_LAZY) diff --git a/package/brew/aikido/ext-aikido.ini b/package/brew/aikido/ext-aikido.ini new file mode 100644 index 000000000..0e63847bb --- /dev/null +++ b/package/brew/aikido/ext-aikido.ini @@ -0,0 +1,3 @@ +; configuration for php aikido module +; priority=20 +extension=aikido.so \ No newline at end of file diff --git a/package/rpm/aikido.spec b/package/rpm/aikido.spec index 58015a430..ad1fd21dc 100644 --- a/package/rpm/aikido.spec +++ b/package/rpm/aikido.spec @@ -81,8 +81,8 @@ else fi fi -mkdir -p /run/aikido-%{version} -chmod 777 /run/aikido-%{version} +mkdir -p /var/run/aikido-%{version} +chmod 777 /var/run/aikido-%{version} echo "Installation process for Aikido v%{version} completed." @@ -150,7 +150,7 @@ fi rm -rf /var/log/aikido-%{version} # Remove the Aikido socket folder -SOCKET_FOLDER="/run/aikido-%{version}" +SOCKET_FOLDER="/var/run/aikido-%{version}" if [ -d "$SOCKET_FOLDER" ]; then echo "Removing $SOCKET_FOLDER ..." diff --git a/tools/build_mac.sh b/tools/build_mac.sh new file mode 100755 index 000000000..1a979187b --- /dev/null +++ b/tools/build_mac.sh @@ -0,0 +1,36 @@ +export PATH="/opt/homebrew/opt/llvm/bin:$PATH" + +PHP_VERSION=$(php -v | ggrep -oP 'PHP \K\d+\.\d+' | head -n 1) +AIKIDO_EXTENSION=aikido-extension-php-$PHP_VERSION.dylib +AIKIDO_EXTENSION_DEBUG=aikido-extension-php-$PHP_VERSION.dylib.debug + +rm -rf build +mkdir build +cd lib +cd php-extension +phpize +cd .. +protoc --go_out=agent --go-grpc_out=agent ipc.proto +protoc --go_out=request-processor --go-grpc_out=request-processor ipc.proto +cd agent +go get google.golang.org/grpc +go test ./... +go build -ldflags "-s -w" -buildmode=c-shared -o ../../build/aikido-agent.dylib +cd ../request-processor +go get google.golang.org/grpc +go get github.com/stretchr/testify/assert +go get github.com/seancfoley/ipaddress-go/ipaddr +go test ./... +go build -ldflags "-s -w" -buildmode=c-shared -o ../../build/aikido-request-processor.dylib +cd ../../build +CXX=clang CXXFLAGS="-fPIC -g -O2 -I../lib/php-extension/include -std=c++17" LDFLAGS="-lstdc++" ../lib/php-extension/configure +make +cd ./modules/ +mv aikido.so $AIKIDO_EXTENSION + +cp $AIKIDO_EXTENSION /opt/homebrew/lib/php/pecl/20210902/$AIKIDO_EXTENSION +# llvm-objcopy --only-keep-debug $AIKIDO_EXTENSION $AIKIDO_EXTENSION_DEBUG +# llvm-objcopy --strip-debug $AIKIDO_EXTENSION +# llvm-objcopy --add-gnu-debuglink=$AIKIDO_EXTENSION_DEBUG $AIKIDO_EXTENSION + +cd ../..