Files
2026-01-16 05:58:35 -08:00

196 lines
3.5 KiB
Go

package console
import (
"strings"
consts "github.com/bishopfox/sliver/client/constants"
"github.com/reeflective/console"
"github.com/spf13/cobra"
)
func (con *SliverClient) allowServerRootCommands(args []string) ([]string, error) {
con.applyCommandFallback(args)
return args, nil
}
func (con *SliverClient) prepareCompletion(line []rune, cursor int) {
if con == nil || con.App == nil {
return
}
menu := con.App.ActiveMenu()
if menu == nil {
return
}
con.setMenuCommandForCompletion(menu, line, cursor)
}
func (con *SliverClient) applyCommandFallback(args []string) {
if con == nil || con.App == nil {
return
}
con.setMenuCommand(con.App.ActiveMenu(), args)
}
func (con *SliverClient) setMenuCommand(menu *console.Menu, args []string) {
if menu == nil {
return
}
if menu.Name() != consts.ImplantMenu {
if menu.Command == nil && con.serverCmds != nil {
menu.Command = con.serverCmds()
}
return
}
if menu.Command == nil {
if con.sliverCmds == nil {
return
}
menu.Command = con.sliverCmds()
}
if con.serverCmds == nil {
return
}
name := firstNonFlagArg(args)
if name == "" {
return
}
if rootHasCommand(menu.Command, name) {
return
}
serverRoot := con.serverCmds()
if serverRoot == nil || !rootHasCommand(serverRoot, name) {
return
}
menu.Command = serverRoot
}
func (con *SliverClient) setMenuCommandForCompletion(menu *console.Menu, line []rune, cursor int) {
if menu == nil || menu.Name() != consts.ImplantMenu {
return
}
if menu.Command == nil {
if con.sliverCmds == nil {
return
}
menu.Command = con.sliverCmds()
}
if con.serverCmds == nil {
return
}
token := firstTokenFromLine(line, cursor)
if token == "" {
return
}
if rootHasCommandPrefix(menu.Command, token) {
return
}
serverRoot := con.serverCmds()
if serverRoot == nil || !rootHasCommandPrefix(serverRoot, token) {
return
}
menu.Command = serverRoot
hideFilteredCommands(menu, menu.Command)
}
func firstNonFlagArg(args []string) string {
for i := 0; i < len(args); i++ {
arg := args[i]
if arg == "--" {
if i+1 < len(args) {
return args[i+1]
}
return ""
}
if strings.HasPrefix(arg, "-") {
continue
}
return arg
}
return ""
}
func firstTokenFromLine(line []rune, cursor int) string {
if cursor > len(line) {
cursor = len(line)
}
if cursor < 0 {
cursor = 0
}
pos := 0
for pos < cursor && isSpace(line[pos]) {
pos++
}
start := pos
for pos < cursor && !isSpace(line[pos]) {
pos++
}
if start == pos {
return ""
}
return string(line[start:pos])
}
func isSpace(r rune) bool {
return r == ' ' || r == '\t' || r == '\n' || r == '\r'
}
func rootHasCommand(root *cobra.Command, name string) bool {
if root == nil || name == "" {
return false
}
for _, cmd := range root.Commands() {
if cmd.Name() == name || cmd.HasAlias(name) {
return true
}
}
return false
}
func rootHasCommandPrefix(root *cobra.Command, prefix string) bool {
if root == nil || prefix == "" {
return false
}
for _, cmd := range root.Commands() {
if strings.HasPrefix(cmd.Name(), prefix) {
return true
}
for _, alias := range cmd.Aliases {
if strings.HasPrefix(alias, prefix) {
return true
}
}
}
return false
}
func hideFilteredCommands(menu *console.Menu, root *cobra.Command) {
if menu == nil || root == nil {
return
}
for _, cmd := range root.Commands() {
if cmd.Hidden {
continue
}
if filters := menu.ActiveFiltersFor(cmd); len(filters) > 0 {
cmd.Hidden = true
}
}
}