summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/cli/cli.go75
-rw-r--r--internal/namespace/launcher_src/launcher.c9
2 files changed, 73 insertions, 11 deletions
diff --git a/internal/cli/cli.go b/internal/cli/cli.go
index aa4268a..13a4a6b 100644
--- a/internal/cli/cli.go
+++ b/internal/cli/cli.go
@@ -21,7 +21,7 @@ func NewApp(args []string) *App {
return &App{Args: args}
}
-func (a *App) Run() error {
+func (a *App) Route() error {
// 1. Validate arguments for null bytes to prevent exec failures in the C launcher
for i, arg := range a.Args {
for j := 0; j < len(arg); j++ {
@@ -31,10 +31,34 @@ func (a *App) Run() error {
}
}
- // Handle the internal diagnostic commands first
+ // Handle the internal diagnostic commands that should run on the HOST
+ if len(a.Args) > 1 {
+ switch a.Args[1] {
+ case "show-config":
+ return a.showConfig()
+ }
+ }
+
+ // Handle subcommands first (profile list, import, configure, delete, stop)
+ if len(a.Args) > 1 && a.Args[1] == "profile" {
+ return a.handleProfileCmd()
+ }
+
+ // If we reach here, we are either wrapping a process or running a command
+ // that requires isolation (e.g., test-ns, test-args).
+ return a.Run()
+}
+
+func (a *App) Run() error {
+ // Handle the internal diagnostic commands that require ISOLATION
if len(a.Args) > 1 {
switch a.Args[1] {
case "test-ns":
+ if !namespace.IsIsolated() {
+ if err := namespace.Bootstrap(); err != nil {
+ return fmt.Errorf("bootstrap failed: %w", err)
+ }
+ }
ok, msg := namespace.VerifyIsolation()
if !ok {
return fmt.Errorf("isolation check failed: %s", msg)
@@ -42,16 +66,15 @@ func (a *App) Run() error {
fmt.Println("Isolation Verified: OK")
return nil
case "test-args":
+ if !namespace.IsIsolated() {
+ if err := namespace.Bootstrap(); err != nil {
+ return fmt.Errorf("bootstrap failed: %w", err)
+ }
+ }
return namespace.VerifyArguments(a.Args)
}
}
- // Handle subcommands first (profile list, import, configure, delete, stop)
- if len(a.Args) > 1 && a.Args[1] == "profile" {
- return a.handleProfileCmd()
- }
- // ...
-
cfg := &config.Config{}
fs := flag.NewFlagSet("wg-wrap", flag.ExitOnError)
@@ -194,3 +217,39 @@ func (a *App) handleProfileCmd() error {
return fmt.Errorf("unknown profile subcommand: %s", subCmd)
}
}
+
+func (a *App) showConfig() error {
+ cfg := &config.Config{}
+ fs := flag.NewFlagSet("wg-wrap", flag.ExitOnError)
+ fs.StringVar(&cfg.Profile, "profile", "default", "WireGuard profile to use")
+ fs.StringVar(&cfg.DNSServer, "dns-server", "", "Override DNS server to use")
+
+ // Parse the arguments that follow 'show-config'
+ if len(a.Args) > 2 {
+ _ = fs.Parse(a.Args[2:])
+ }
+
+ // Determine runtime base directory
+ runtimeBase := a.RuntimeBaseDir
+ if runtimeBase == "" {
+ runtimeBase = os.Getenv("XDG_RUNTIME_DIR")
+ if runtimeBase == "" {
+ runtimeBase = fmt.Sprintf("/run/user/%d", os.Getuid())
+ }
+ }
+
+ // Resolve paths
+ profilePath := namespace.GetProfileNamespacePath(runtimeBase, cfg.Profile)
+ pidsPath := namespace.GetPidsDirPath(runtimeBase, cfg.Profile)
+
+ fmt.Printf("Configuration:\n")
+ fmt.Printf(" Profile: %s\n", cfg.Profile)
+ fmt.Printf(" DNS Server: %s\n", cfg.DNSServer)
+ fmt.Printf(" Runtime Base: %s\n", runtimeBase)
+ fmt.Printf(" Profile Path: %s\n", profilePath)
+ fmt.Printf(" PIDs Path: %s\n", pidsPath)
+ fmt.Printf(" Isolated: %v\n", namespace.IsIsolated())
+ fmt.Printf(" UID: %d\n", os.Getuid())
+
+ return nil
+}
diff --git a/internal/namespace/launcher_src/launcher.c b/internal/namespace/launcher_src/launcher.c
index 63dd6ff..4311430 100644
--- a/internal/namespace/launcher_src/launcher.c
+++ b/internal/namespace/launcher_src/launcher.c
@@ -65,12 +65,15 @@ int main(int argc, char **argv) {
// as the first element of the argv array.
// Therefore, argv[0] is the path to the binary we want to execute.
if (argv[0] == NULL) {
- fprintf(stderr, "No target binary provided in argv[0]\n");
+ fprintf(stderr, "No target binary provided in argv[0]\\n");
return 1;
}
- // Use execv instead of execvp to avoid PATH search issues
- // since we are providing an absolute path from Go.
+ // Prepare a new argv for the target command.
+ // We want the target binary to see itself as argv[0].
+ // The current argv is [target_binary, arg1, arg2, ...].
+ // execv expects argv[0] to be the filename, and the rest as arguments.
+ // This is already the case here, but let's be explicit.
if (execv(argv[0], argv) == -1) {
perror("execv failed");
return 1;