diff --git a/internal/platform/platform_common_maven.go b/internal/platform/platform_common_maven.go new file mode 100644 index 00000000..066c8506 --- /dev/null +++ b/internal/platform/platform_common_maven.go @@ -0,0 +1,62 @@ +package platform + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/AikidoSec/safechain-internals/internal/utils" +) + +func installMavenRcOverride(mavenrcPath, startMarker, endMarker, contentLine string, filePerm os.FileMode) error { + filename := filepath.Base(mavenrcPath) + + content := "" + if data, err := os.ReadFile(mavenrcPath); err == nil { + content = string(data) + } else if !os.IsNotExist(err) { + return fmt.Errorf("failed to read %s: %w", filename, err) + } + + if strings.Contains(content, startMarker) { + if !strings.Contains(content, endMarker) { + return fmt.Errorf("found start marker in %s but not end marker - corrupt configuration", filename) + } + return nil + } + + lineEnding := "\n" + if strings.Contains(content, "\r\n") { + lineEnding = "\r\n" + } + + if content != "" && !strings.HasSuffix(content, "\n") && !strings.HasSuffix(content, "\r\n") { + content += lineEnding + } + + block := strings.Join([]string{startMarker, contentLine, endMarker}, lineEnding) + lineEnding + return os.WriteFile(mavenrcPath, []byte(content+block), filePerm) +} + +func uninstallMavenRcOverride(mavenrcPath, startMarker, endMarker string, filePerm os.FileMode) error { + filename := filepath.Base(mavenrcPath) + + data, err := os.ReadFile(mavenrcPath) + if err != nil { + if os.IsNotExist(err) { + return nil + } + return fmt.Errorf("failed to read %s: %w", filename, err) + } + + newContent, removed, err := utils.RemoveMarkedBlock(string(data), startMarker, endMarker) + if err != nil { + return err + } + if !removed { + return nil + } + + return os.WriteFile(mavenrcPath, []byte(newContent), filePerm) +} diff --git a/internal/platform/platform_darwin_maven.go b/internal/platform/platform_darwin_maven.go index 502397f7..39d5a3ec 100644 --- a/internal/platform/platform_darwin_maven.go +++ b/internal/platform/platform_darwin_maven.go @@ -3,65 +3,40 @@ package platform import ( - "fmt" "os" "path/filepath" - "strings" - - "github.com/AikidoSec/safechain-internals/internal/utils" ) const ( mavenRcMarkerStart = "# aikido-safe-chain-start" mavenRcMarkerEnd = "# aikido-safe-chain-end" - mavenRcBlock = mavenRcMarkerStart + "\n" + - `export MAVEN_OPTS="$MAVEN_OPTS -Daikido.safechain.mavenopts=true -Djavax.net.ssl.trustStoreType=KeychainStore -Djavax.net.ssl.trustStore=NONE"` + "\n" + - mavenRcMarkerEnd + "\n" - mavenRcFilePerm = 0o644 + mavenRcFilePerm = 0o644 + mavenRcFilename = ".mavenrc" + mavenRcLine = `export MAVEN_OPTS="$MAVEN_OPTS -Daikido.safechain.mavenopts=true -Djavax.net.ssl.trustStoreType=KeychainStore -Djavax.net.ssl.trustStore=NONE"` ) func InstallMavenOptsOverride(homeDir string) error { - mavenrcPath := filepath.Join(homeDir, ".mavenrc") - - content := "" - if data, err := os.ReadFile(mavenrcPath); err == nil { - content = string(data) - } else if !os.IsNotExist(err) { - return fmt.Errorf("failed to read .mavenrc: %w", err) - } - - if strings.Contains(content, mavenRcMarkerStart) { - if !strings.Contains(content, mavenRcMarkerEnd) { - return fmt.Errorf("found start marker in .mavenrc but not end marker - corrupt configuration") - } - return nil - } - - if content != "" && !strings.HasSuffix(content, "\n") { - content += "\n" - } - - return os.WriteFile(mavenrcPath, []byte(content+mavenRcBlock), mavenRcFilePerm) + mavenrcPath := filepath.Join(homeDir, mavenRcFilename) + return installMavenRcOverride(mavenrcPath, + mavenRcMarkerStart, + mavenRcMarkerEnd, + mavenRcLine, + mavenRcFilePerm, + ) } func UninstallMavenOptsOverride(homeDir string) error { - mavenrcPath := filepath.Join(homeDir, ".mavenrc") - - data, err := os.ReadFile(mavenrcPath) - if err != nil { - if os.IsNotExist(err) { - return nil - } - return fmt.Errorf("failed to read .mavenrc: %w", err) - } + mavenrcPath := filepath.Join(homeDir, mavenRcFilename) + return uninstallMavenRcOverride(mavenrcPath, + mavenRcMarkerStart, + mavenRcMarkerEnd, + mavenRcFilePerm, + ) +} - newContent, removed, err := utils.RemoveMarkedBlock(string(data), mavenRcMarkerStart, mavenRcMarkerEnd) - if err != nil { - return err - } - if !removed { - return nil +func GetMavenHomeDir() (string, error) { + if config.HomeDir != "" { + return config.HomeDir, nil } - - return os.WriteFile(mavenrcPath, []byte(newContent), mavenRcFilePerm) + return os.UserHomeDir() } diff --git a/internal/platform/platform_other_maven.go b/internal/platform/platform_other_maven.go index 814b9817..bb20f73e 100644 --- a/internal/platform/platform_other_maven.go +++ b/internal/platform/platform_other_maven.go @@ -2,6 +2,15 @@ package platform +import "os" + func InstallMavenOptsOverride(_ string) error { return nil } func UninstallMavenOptsOverride(_ string) error { return nil } + +func GetMavenHomeDir() (string, error) { + if config.HomeDir != "" { + return config.HomeDir, nil + } + return os.UserHomeDir() +} diff --git a/internal/platform/platform_windows_maven.go b/internal/platform/platform_windows_maven.go index 2343643d..4290a111 100644 --- a/internal/platform/platform_windows_maven.go +++ b/internal/platform/platform_windows_maven.go @@ -2,6 +2,35 @@ package platform -func InstallMavenOptsOverride(_ string) error { return nil } +import "path/filepath" -func UninstallMavenOptsOverride(_ string) error { return nil } +const ( + mavenRcMarkerStart = "REM aikido-safe-chain-start" + mavenRcMarkerEnd = "REM aikido-safe-chain-end" + mavenRcFilePerm = 0o644 + mavenRcFilename = "mavenrc_pre.cmd" + mavenRcLine = `set "MAVEN_OPTS=%MAVEN_OPTS% -Daikido.safechain.mavenopts=true -Djavax.net.ssl.trustStoreType=Windows-ROOT -Djavax.net.ssl.trustStore=NONE"` +) + +func InstallMavenOptsOverride(homeDir string) error { + return installMavenRcOverride( + filepath.Join(homeDir, mavenRcFilename), + mavenRcMarkerStart, + mavenRcMarkerEnd, + mavenRcLine, + mavenRcFilePerm, + ) +} + +func UninstallMavenOptsOverride(homeDir string) error { + return uninstallMavenRcOverride( + filepath.Join(homeDir, mavenRcFilename), + mavenRcMarkerStart, + mavenRcMarkerEnd, + mavenRcFilePerm, + ) +} + +func GetMavenHomeDir() (string, error) { + return GetActiveUserHomeDir() +} diff --git a/internal/setup/steps/02_configure_maven/step.go b/internal/setup/steps/02_configure_maven/step.go index 8373ca2a..fd5d11bd 100644 --- a/internal/setup/steps/02_configure_maven/step.go +++ b/internal/setup/steps/02_configure_maven/step.go @@ -48,14 +48,17 @@ func (s *Step) Install(ctx context.Context) error { return fmt.Errorf("invalid proxy URL: missing host or port (got host=%q, port=%q)", host, port) } - homeDir := platform.GetConfig().HomeDir + homeDir, err := platform.GetMavenHomeDir() + if err != nil { + return fmt.Errorf("failed to resolve user home directory: %v", err) + } // Configure Maven proxy settings if err := installMavenProxySetting(homeDir, host, port); err != nil { log.Printf("Warning: failed to configure Maven proxy settings: %v", err) } - // Configure MAVEN_OPTS to use system truststore on macOS + // Configure MAVEN_OPTS to use the OS truststore if err := platform.InstallMavenOptsOverride(homeDir); err != nil { log.Printf("Warning: failed to persist MAVEN_OPTS truststore override: %v", err) } @@ -65,7 +68,10 @@ func (s *Step) Install(ctx context.Context) error { } func (s *Step) Uninstall(ctx context.Context) error { - homeDir := platform.GetConfig().HomeDir + homeDir, err := platform.GetMavenHomeDir() + if err != nil { + return fmt.Errorf("failed to resolve user home directory: %v", err) + } if err := uninstallMavenProxySetting(homeDir); err != nil { log.Printf("Warning: failed to remove Maven proxy settings: %v", err)