@@ -2,7 +2,9 @@ package console
22
33import (
44 "fmt"
5+ "os"
56 "os/exec"
7+ "path/filepath"
68 "strings"
79
810 log "github.com/sirupsen/logrus"
@@ -14,7 +16,7 @@ func RunCmd(sudo bool, command string, args ...string) (string, error) {
1416
1517 var stdout strings.Builder
1618 var stderr strings.Builder
17-
19+
1820 if sudo {
1921 // Check if sudo is available
2022 _ , err := exec .LookPath ("sudo" )
@@ -26,7 +28,7 @@ func RunCmd(sudo bool, command string, args ...string) (string, error) {
2628 }
2729 } else {
2830 cmd = exec .Command (command , args ... )
29- }
31+ }
3032
3133 cmd .Stdout = & stdout
3234 cmd .Stderr = & stderr
@@ -37,4 +39,107 @@ func RunCmd(sudo bool, command string, args ...string) (string, error) {
3739 }
3840
3941 return stdout .String (), nil
40- }
42+ }
43+
44+ func WgShow () (string , error ) {
45+ var stdout strings.Builder
46+ var stderr strings.Builder
47+
48+ cmd := exec .Command ("sudo" , "wg" , "show" )
49+
50+ cmd .Stdout = & stdout
51+ cmd .Stderr = & stderr
52+
53+ err := cmd .Run ()
54+ if err != nil {
55+ return stdout .String (), fmt .Errorf ("wg show command execution failed: %w, stderr: %v, stdout: %v" , err , stderr .String (), stdout .String ())
56+ }
57+
58+ return stdout .String (), nil
59+ }
60+
61+ func WgUp (cfgPath string ) error {
62+ cleanedPath , err := sanitizeWgConfigPath (cfgPath )
63+ if err != nil {
64+ return fmt .Errorf ("invalid WireGuard config path: %w" , err )
65+ }
66+
67+ var stdout strings.Builder
68+ var stderr strings.Builder
69+
70+ cmd := exec .Command ("sudo" , "wg-quick" , "up" , cleanedPath )
71+
72+ cmd .Stdout = & stdout
73+ cmd .Stderr = & stderr
74+
75+ err = cmd .Run ()
76+ if err != nil {
77+ return fmt .Errorf ("wg-quick up command execution failed: %w, stderr: %v, stdout: %v" , err , stderr .String (), stdout .String ())
78+ }
79+
80+ return nil
81+ }
82+
83+ func WgDown (cfgPath string ) error {
84+ cleanedPath , err := sanitizeWgConfigPath (cfgPath )
85+ if err != nil {
86+ return fmt .Errorf ("invalid WireGuard config path: %w" , err )
87+ }
88+
89+ var stdout strings.Builder
90+ var stderr strings.Builder
91+
92+ cmd := exec .Command ("sudo" , "wg-quick" , "down" , cleanedPath )
93+
94+ cmd .Stdout = & stdout
95+ cmd .Stderr = & stderr
96+
97+ err = cmd .Run ()
98+ if err != nil {
99+ return fmt .Errorf ("wg-quick down command execution failed: %w, stderr: %v, stdout: %v" , err , stderr .String (), stdout .String ())
100+ }
101+
102+ return nil
103+ }
104+
105+ func sanitizeWgConfigPath (cfgPath string ) (string , error ) {
106+ // Clean the path (removes .., redundant separators, etc.)
107+ cleanPath := filepath .Clean (cfgPath )
108+
109+ // Expand home directory if present
110+ home , err := os .UserHomeDir ()
111+ if err != nil {
112+ return "" , fmt .Errorf ("failed to get home directory: %w" , err )
113+ } else if strings .HasPrefix (cleanPath , "~/" ) {
114+ cleanPath = filepath .Join (home , cleanPath [2 :])
115+ }
116+
117+ // Convert to absolute path
118+ absPath , err := filepath .Abs (cleanPath )
119+ if err != nil {
120+ return "" , fmt .Errorf ("failed to resolve absolute path: %w" , err )
121+ }
122+
123+ // Verify the file exists and is a regular file
124+ fileInfo , err := os .Stat (absPath )
125+ if err != nil {
126+ return "" , fmt .Errorf ("config file not accessible: %w" , err )
127+ }
128+
129+ if ! fileInfo .Mode ().IsRegular () {
130+ return "" , fmt .Errorf ("config path is not a regular file" )
131+ }
132+
133+ // Ensure it's within the expected config directory
134+ expectedBase := filepath .Join (home , ".config" , "mbvpn" , "servers" )
135+ if ! strings .HasPrefix (absPath , expectedBase ) {
136+ return "" , fmt .Errorf ("config file must be within %s" , expectedBase )
137+ }
138+
139+ // Verify file extension (WireGuard configs must be .conf)
140+ if filepath .Ext (absPath ) != ".conf" {
141+ return "" , fmt .Errorf ("config file must have .conf extension" )
142+ }
143+
144+ return absPath , nil
145+ }
0 commit comments