Skip to content

Commit 7b12c1e

Browse files
author
mirkobrombin
committed
feat: Add an option to restrict the commands that can be run
1 parent 6486e01 commit 7b12c1e

2 files changed

Lines changed: 55 additions & 20 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ problem on those systems where Flatpak or DBus are not available.
3636

3737
## What is left to do?
3838

39-
- [ ] Add an option to restrict the commands that can be run
39+
- [x] Add an option to restrict the commands that can be run
4040
- [x] Add support for creating shims for host binaries
4141
- [ ] Switch from TCP to Unix sockets
4242
- [ ] Code optimization

main.go

Lines changed: 54 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"bufio"
55
"encoding/json"
6+
"flag"
67
"fmt"
78
"io"
89
"log"
@@ -26,37 +27,55 @@ type Command struct {
2627
}
2728

2829
func main() {
29-
// Start the server if the first argument is "start"
30-
if len(os.Args) > 1 && os.Args[1] == "start" {
31-
startServer()
32-
return
30+
helpFlag := flag.Bool("h", false, "Display help")
31+
helpFlagLong := flag.Bool("help", false, "Display help")
32+
startFlag := flag.Bool("start", false, "Start the server")
33+
allowedCmds := make([]string, 0)
34+
flag.Func("allowed-cmd", "Specify allowed command (can be used multiple times)", func(cmd string) error {
35+
allowedCmds = append(allowedCmds, cmd)
36+
return nil
37+
})
38+
39+
flag.Usage = func() {
40+
fmt.Fprintf(os.Stderr, `Usage: hrun [options] [command] [args...]
41+
42+
Options:
43+
-h, --help Display this help message.
44+
--start Start the server.
45+
--allowed-cmd Specify allowed command (can be used multiple times).
46+
47+
If command is "start", it starts the server with specified allowed commands.
48+
Otherwise, it starts the client and sends the command to the server.
49+
If no command is provided, it starts a shell on the host.
50+
`)
3351
}
3452

35-
// Print help message if the first argument is "-h" or "--help"
36-
if len(os.Args) > 1 && (os.Args[1] == "-h" || os.Args[1] == "--help") {
37-
log.Println(`Usage: hrun [options] command [args...]
53+
flag.Parse()
54+
55+
// Help message
56+
if *helpFlag || *helpFlagLong {
57+
flag.Usage()
58+
return
59+
}
3860

39-
If command is "start", it starts the server. Otherwise, it starts the client
40-
and sends the command to the server. If no command is provided, it starts a
41-
shell on the host.`)
61+
// Server mode
62+
if *startFlag {
63+
startServer(allowedCmds)
4264
return
4365
}
4466

45-
// Start the client otherwise
67+
// Client mode
4668
var command []string
47-
if path.Base(os.Args[0]) == "hrun" {
69+
if path.Base(os.Args[0]) == "hrun" && len(flag.Args()) == 0 {
4870
command = []string{"sh", "-c", os.Getenv("SHELL")}
49-
if len(os.Args) > 1 {
50-
command = os.Args[1:]
51-
}
5271
} else {
53-
command = append([]string{path.Base(os.Args[0])}, os.Args[1:]...)
72+
command = flag.Args()
5473
}
5574

5675
startClient(command)
5776
}
5877

59-
func startServer() {
78+
func startServer(allowedCmds []string) {
6079
// Create a listener for the server
6180
listener, err := net.Listen("tcp", "127.0.0.1:8080")
6281
if err != nil {
@@ -87,7 +106,7 @@ func startServer() {
87106
log.Println("Listener closed, shutting down server...")
88107
return
89108
}
90-
go handleConnection(conn)
109+
go handleConnection(conn, allowedCmds)
91110
}
92111
}
93112
}
@@ -106,7 +125,7 @@ func acceptConn(listener net.Listener) <-chan net.Conn {
106125
return ch
107126
}
108127

109-
func handleConnection(conn net.Conn) {
128+
func handleConnection(conn net.Conn, allowedCmds []string) {
110129
defer conn.Close()
111130

112131
// Read the command from the client
@@ -130,6 +149,22 @@ func handleConnection(conn net.Conn) {
130149
return
131150
}
132151

152+
// Check if the command is allowed
153+
if len(allowedCmds) > 0 {
154+
allowed := false
155+
for _, allowedCmd := range allowedCmds {
156+
if cmdStruct.Command[0] == allowedCmd {
157+
allowed = true
158+
break
159+
}
160+
}
161+
if !allowed {
162+
log.Printf("Command %s is not allowed", cmdStruct.Command[0])
163+
conn.Close()
164+
return
165+
}
166+
}
167+
133168
// Prepare a pty
134169
var ptyMaster, ptySlave *os.File
135170
ptyMaster, ptySlave, err = pty.Open()

0 commit comments

Comments
 (0)