Skip to content

Commit eb2debd

Browse files
committed
[#72940] linux-client: Support spawning reverse shell
Signed-off-by: Łukasz Kędziora <lkedziora@antmicro.com>
1 parent 588735b commit eb2debd

File tree

3 files changed

+54
-4
lines changed

3 files changed

+54
-4
lines changed

devices/linux-client/daemon/daemonize.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ func Daemonize(c *libcli.Context) error {
4343
log.Errorln("Failed to setup action runner:", err)
4444
return err
4545
}
46+
err = device.setupShellRunner()
47+
if err != nil {
48+
log.Errorln("Failed to setup shell runner:", err)
49+
return err
50+
}
4651

4752
channel := make(chan os.Signal)
4853
signal.Notify(channel, syscall.SIGINT, syscall.SIGTERM)

devices/linux-client/daemon/device.go

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"github.com/antmicro/rdfm/app"
2828
"github.com/antmicro/rdfm/conf"
2929
"github.com/antmicro/rdfm/serverws"
30+
"github.com/antmicro/rdfm/shell"
3031
"github.com/antmicro/rdfm/telemetry"
3132

3233
netUtils "github.com/antmicro/rdfm/daemon/net_utils"
@@ -48,6 +49,7 @@ type Device struct {
4849
logManager *telemetry.LogManager
4950
conn *serverws.DeviceManagementConnection
5051
actionRunner *actions.ActionRunner
52+
shellRunner *shell.ShellRunner
5153
}
5254

5355
func (d *Device) handleRequest(msg []byte) (serverws.Request, error) {
@@ -107,8 +109,40 @@ func (d *Device) handleRequest(msg []byte) (serverws.Request, error) {
107109
Actions: reqActions,
108110
}
109111
return response, nil
110-
//case serverws.DeviceAttachToManager:
111-
// TODO: Handle shell_attach
112+
case serverws.DeviceAttachToManager:
113+
tlsConf, err := d.getTlsConf()
114+
if err != nil {
115+
log.Warnln("Failed to get TLS configuration:", err)
116+
return nil, nil
117+
}
118+
119+
go func() {
120+
token, err := d.getDeviceToken()
121+
if err != nil {
122+
log.Warnln("Failed to acquire device token:", err)
123+
return
124+
}
125+
126+
session, err := d.shellRunner.Spawn(r.Uuid)
127+
if err != nil {
128+
log.Warnln("Failed to spawn shell session:", err)
129+
return
130+
}
131+
defer d.shellRunner.Terminate(session.Uuid())
132+
133+
conn := serverws.NewShellConnection(d.rdfmCtx.RdfmConfig.ServerURL, tlsConf)
134+
err = conn.Connect(token, r.MacAddr, r.Uuid)
135+
if err != nil {
136+
log.Warnln("Failed to connect to shell WebSocket:", err)
137+
return
138+
}
139+
defer conn.Close()
140+
141+
err = session.Run(conn)
142+
log.Debugf("Shell session %s exited with err: %s", session.Uuid(), err)
143+
}()
144+
145+
return nil, nil
112146
default:
113147
log.Warnf("Request '%s' is unsupported", requestName)
114148
response := serverws.CantHandleRequest()
@@ -206,7 +240,7 @@ func (d *Device) setupConnection() error {
206240
// config file instead, but we don't have any configuration options that
207241
// determine whether action/shell should be enabled or not.
208242
d.conn.SetCapability("action", true)
209-
d.conn.SetCapability("shell", false)
243+
d.conn.SetCapability("shell", true)
210244
return nil
211245
}
212246

@@ -219,6 +253,15 @@ func (d *Device) setupActionRunner() error {
219253
return nil
220254
}
221255

256+
func (d *Device) setupShellRunner() error {
257+
sr, err := shell.NewShellRunner(1)
258+
if err != nil {
259+
return err
260+
}
261+
d.shellRunner = sr
262+
return nil
263+
}
264+
222265
func (d *Device) actionResultCallback(result actions.ActionResult, cancelCtx context.Context) bool {
223266
res := serverws.ActionExecResult{
224267
Method: "action_exec_result",

devices/linux-client/serverws/requests.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,9 @@ func Parse(r string) (Request, error) {
120120
err = json.Unmarshal([]byte(r), &parsed)
121121
return parsed, err
122122
case "shell_attach":
123-
// TODO: reverse shell support
123+
var parsed DeviceAttachToManager
124+
err = json.Unmarshal([]byte(r), &parsed)
125+
return parsed, err
124126
case "action_exec":
125127
var parsed ActionExec
126128
err = json.Unmarshal([]byte(r), &parsed)

0 commit comments

Comments
 (0)