sshpiper/plugin/workingdir/workingdir.go
Boshi Lian 14ceadb8e8
add skel plugin for code sharing (#473)
* introduce plugin skel to reuse code

* Refactor code to use libplugin.NewSkelPlugin for plugin/kubernetes/main.go
Add YAML Plugin skel.go for plugin/yaml

* Fix code scanning alert no. 6: Incorrect conversion between integer types

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* fix gpt

* fjx password handling in SkelPlugin and skelpipeToWrapper

* go fmt

* Refactor Docker plugin to use skelpipe wrapper

* Refactor skel.go to use container username instead of client username

* revert yaml test order

* fix public and password mess up

* Refactor working dir to use skel

* revert deleted file

* Refactor skel.go to remove unused code and simplify MatchConn function

* Refactor skel.go to read userKnownHosts file in KnownHosts function

* remove workingdirbykey from goreleaser

* Refactor workingdir.go to use libplugin.SplitHostPortForSSH for parsing host and port

* Refactor skel.go to remove unused code and simplify MatchConn function

* merge doc into workingdir

---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2024-10-24 23:15:26 -07:00

109 lines
2 KiB
Go

package main
import (
"bufio"
"fmt"
"os"
"path"
"regexp"
"strings"
"github.com/tg123/sshpiper/libplugin"
)
type workingdir struct {
Path string
NoCheckPerm bool
Strict bool
}
var (
// Base username validation on Debians default: https://sources.debian.net/src/adduser/3.113%2Bnmu3/adduser.conf/#L85
// -> NAME_REGEX="^[a-z][-a-z0-9_]*\$"
// The length is limited to 32 characters. See man 8 useradd: https://linux.die.net/man/8/useradd
usernameRule *regexp.Regexp = regexp.MustCompile("^[a-z_][-a-z0-9_]{0,31}$")
)
const (
userAuthorizedKeysFile = "authorized_keys"
userKeyFile = "id_rsa"
userUpstreamFile = "sshpiper_upstream"
userKnownHosts = "known_hosts"
)
func isUsernameSecure(user string) bool {
return usernameRule.MatchString(user)
}
func (w *workingdir) checkPerm(file string) error {
filename := path.Join(w.Path, file)
f, err := os.Open(filename)
if err != nil {
return err
}
defer f.Close()
fi, err := f.Stat()
if err != nil {
return err
}
if w.NoCheckPerm {
return nil
}
if fi.Mode().Perm()&0077 != 0 {
return fmt.Errorf("%v's perm is too open", filename)
}
return nil
}
func (w *workingdir) fullpath(file string) string {
return path.Join(w.Path, file)
}
func (w *workingdir) Readfile(file string) ([]byte, error) {
if err := w.checkPerm(file); err != nil {
return nil, err
}
return os.ReadFile(w.fullpath(file))
}
func (w *workingdir) Exists(file string) bool {
info, err := os.Stat(w.fullpath(file))
if os.IsNotExist(err) {
return false
}
return !info.IsDir()
}
// TODO refactor this
func parseUpstreamFile(data string) (host string, user string, err error) {
r := bufio.NewReader(strings.NewReader(data))
for {
host, err = r.ReadString('\n')
if err != nil {
break
}
host = strings.TrimSpace(host)
if host != "" && host[0] != '#' {
break
}
}
t := strings.SplitN(host, "@", 2)
if len(t) > 1 {
user = t[0]
host = t[1]
}
_, _, err = libplugin.SplitHostPortForSSH(host)
return
}