diff --git a/cmd/packets/main.go b/cmd/packets/main.go index 50eace8..97f6d76 100644 --- a/cmd/packets/main.go +++ b/cmd/packets/main.go @@ -160,11 +160,10 @@ var installCmd = &cobra.Command{ log.Fatal("index.db does not exist, try to use \"packets sync\"") } } - f, err := os.OpenFile(consts.InstalledDB, os.O_WRONLY, 0) - if err != nil { - log.Fatalf("can't open [ %s ]. Are you running packets as root?\n", consts.InstalledDB) + + if os.Getuid() != 0 { + log.Fatal("you must run this command as root") } - f.Close() db, err := sql.Open("sqlite", consts.IndexDB) if err != nil { @@ -436,7 +435,12 @@ var removeCmd = &cobra.Command{ Args: cobra.MinimumNArgs(1), Short: "Remove a package from the given names", Run: func(cmd *cobra.Command, args []string) { - fmt.Print(":: This command will remove permanently this packages, are you sure? (y/N)\n>> ") + + if os.Getuid() != 0 { + log.Fatal("you must run this command as root") + } + + fmt.Print("WARNING: This command will remove permanently this packages, are you sure? (y/N) ") var a string fmt.Scanf("%s", &a) if a != "y" && a != "Y" { @@ -468,6 +472,7 @@ var removeCmd = &cobra.Command{ if err != nil { log.Fatal(err) } + fmt.Println(":: Removing", pkgName) packets.ExecuteRemoveScript(filepath.Join(packageDir, manifest.Hooks.Remove)) diff --git a/internal/utils/lua/lua.go b/internal/utils/lua/lua.go index 4ab0edd..28a7b4c 100644 --- a/internal/utils/lua/lua.go +++ b/internal/utils/lua/lua.go @@ -28,16 +28,6 @@ func GetSandBox(sandboxdir string) (lua.LState, error) { L.SetGlobal("path_join", L.NewFunction(Ljoin)) // Packets build functions - build := L.NewTable() - - L.SetField(build, "requirements", L.NewFunction(LCompileRequirements)) - L.SetField(build, "compile", L.NewFunction(LCompile)) - - L.SetGlobal("build", build) - - osObject.RawSetString("execute", lua.LNil) - osObject.RawSetString("exit", lua.LNil) - osObject.RawSetString("getenv", lua.LNil) osObject.RawSetString("remove", L.NewFunction(LSafeRemove)) osObject.RawSetString("rename", L.NewFunction(LSafeRename)) @@ -53,7 +43,7 @@ func GetSandBox(sandboxdir string) (lua.LState, error) { ioObject.RawSetString("stderr", lua.LNil) ioObject.RawSetString("stdin", lua.LNil) ioObject.RawSetString("lines", lua.LNil) - ioObject.RawSetString("open", L.NewFunction(LOpen)) + //ioObject.RawSetString("open", L.NewFunction(LOpen)) return *L, nil } diff --git a/internal/utils/lua/luafunctions.go b/internal/utils/lua/luafunctions.go index d6f1ed2..ef11b33 100644 --- a/internal/utils/lua/luafunctions.go +++ b/internal/utils/lua/luafunctions.go @@ -4,7 +4,6 @@ import ( "fmt" "log" "os" - "os/exec" "packets/configs" "packets/internal/consts" "packets/internal/utils" @@ -121,11 +120,6 @@ func LSafeRemove(L *lua.LState) int { filename := L.CheckString(1) fmt.Printf(" remove %s\n", filename) - if !IsSafe(filename) { - L.Push(lua.LFalse) - L.Push(lua.LString("unsafe filepath")) - return 2 - } err := os.RemoveAll(filename) if err != nil { L.Push(lua.LFalse) @@ -142,11 +136,6 @@ func LSafeRename(L *lua.LState) int { newname := L.CheckString(2) fmt.Printf(" move %s -> %s\n", oldname, newname) - if !IsSafe(oldname) || !IsSafe(newname) { - L.Push(lua.LFalse) - L.Push(lua.LString("unsafe filepath")) - return 2 - } if err := os.Rename(oldname, newname); err != nil { L.Push(lua.LFalse) @@ -163,12 +152,6 @@ func LSafeCopy(L *lua.LState) int { fmt.Printf(" copy %s -> %s\n", oldname, newname) - if !IsSafe(oldname) || !IsSafe(newname) { - L.Push(lua.LFalse) - L.Push(lua.LString("[packets] unsafe filepath")) - return 2 - } - if err := utils.CopyDir(oldname, newname); err != nil { L.Push(lua.LFalse) L.Push(lua.LString(err.Error())) @@ -187,12 +170,6 @@ func LSymlink(L *lua.LState) int { fmt.Printf(" symlink %s -> %s\n", fileName, destination) - if !IsSafe(fileName) || !IsSafe(destination) { - L.Push(lua.LFalse) - L.Push(lua.LString("[packets] unsafe filepath")) - return 2 - } - _ = os.RemoveAll(destination) if err := os.Symlink(fileName, destination); err != nil { L.Push(lua.LFalse) @@ -224,15 +201,11 @@ func modeFlags(mode string) int { } } +/* func LOpen(L *lua.LState) int { path := L.CheckString(1) mode := L.OptString(2, "r") - if !IsSafe(path) { - L.Push(lua.LNil) - L.Push(lua.LString("unsafe filepath")) - return 2 - } file, err := os.OpenFile(path, modeFlags(mode), 0644) if err != nil { L.Push(lua.LNil) @@ -247,6 +220,7 @@ func LOpen(L *lua.LState) int { L.Push(lua.LNil) return 2 } +*/ func Ljoin(L *lua.LState) int { @@ -268,113 +242,15 @@ func LMkdir(L *lua.LState) int { perm := L.CheckInt(2) fmt.Printf(" mkdir %s \n", path) - if !IsSafe(path) { - L.Push(lua.LFalse) - L.Push(lua.LString("unsafe filepath")) - return 2 - } - - if err := os.MkdirAll(path, os.FileMode(perm)); err != nil { - L.Push(lua.LFalse) - L.Push(lua.LString(err.Error())) - return 2 - } - - L.Push(lua.LTrue) - L.Push(lua.LNil) - return 2 -} - -func LCompile(L *lua.LState) int { - lang := L.CheckString(1) - args := []string{} - for i := 2; i <= L.GetTop(); i++ { - - if strings.Contains(L.CheckString(i), "/") { - - tryintoacess, err := filepath.Abs(filepath.Clean(filepath.Join(SandboxDir, L.CheckString(i)))) - if err != nil { - L.Push(lua.LFalse) - L.Push(lua.LString(err.Error())) - return 2 - } - - rel, err := filepath.Rel(SandboxDir, tryintoacess) - if err != nil || strings.HasPrefix(rel, "..") { - L.Push(lua.LFalse) - L.Push(lua.LString("unsafe filepath")) - return 2 - } - } - - args = append(args, L.CheckString(i)) - } - - bin, suc := AllowedCmds[lang] - if !suc { - L.Push(lua.LFalse) - L.Push(lua.LString("unsupported language")) - return 2 - } - - cmd := exec.Command(bin, args...) - cmd.Dir = SandboxDir - out, err := cmd.CombinedOutput() - fmt.Printf(" compiling with %s", bin) - if err != nil { - L.Push(lua.LFalse) - L.Push(lua.LString(err.Error() + "\n" + string(out))) - return 2 - } - if err := cmd.Run(); err != nil { - L.Push(lua.LFalse) - L.Push(lua.LString(err.Error())) - return 2 - } - - L.Push(lua.LTrue) - L.Push(lua.LString(string(out))) - return 2 -} - -func LCompileRequirements(L *lua.LState) int { - - cmdLang := L.CheckString(1) - - if strings.Contains(L.CheckString(2), "/") { - - tryintoacess, err := filepath.Abs(filepath.Clean(L.CheckString(2))) - if err != nil { - L.Push(lua.LFalse) - L.Push(lua.LString(err.Error())) - return 2 - } - if !strings.HasPrefix(tryintoacess, SandboxDir) { + /* + if !IsSafe(path) { L.Push(lua.LFalse) L.Push(lua.LString("unsafe filepath")) return 2 } - } + */ - var err error - - fmt.Printf(" installing requirements with %s", cmdLang) - switch cmdLang { - case "python": - cmd := exec.Command("pip", "install", "--target", filepath.Join(SandboxDir, "tmp/build"), "-r", L.CheckString(2)) - cmd.Dir = filepath.Join(SandboxDir, "data") - err = cmd.Run() - case "java": - cmd := exec.Command("mvn", "dependency:copy-dependencies", "-DoutputDirectory="+filepath.Join(SandboxDir, "tmp/build")) - cmd.Dir = L.CheckString(2) - err = cmd.Run() - case "ruby": - cmd := exec.Command("bundle", "install", "--path", filepath.Join(SandboxDir, "tmp/build")) - cmd.Dir = L.CheckString(2) - err = cmd.Run() - } - - if err != nil { + if err := os.MkdirAll(path, os.FileMode(perm)); err != nil { L.Push(lua.LFalse) L.Push(lua.LString(err.Error())) return 2 diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 864ef13..bb2ed01 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -10,9 +10,12 @@ import ( "log" "net/http" "os" + "os/exec" "path" "path/filepath" + "strconv" "strings" + "syscall" "packets/configs" "packets/internal/consts" @@ -393,3 +396,34 @@ skipping: return this, nil } + +func GetPacketsUID() (int, error) { + _ = exec.Command("useradd", "-M", "-N", "packets").Run() + cmd := exec.Command("id", "-u", "packets") + + out, err := cmd.CombinedOutput() + if err != nil { + return -1, err + } + + s := strings.TrimSpace(string(out)) + uid, err := strconv.Atoi(s) + if err != nil { + return -1, err + } + return uid, nil +} + +func ChangeToNoPermission() error { + _ = exec.Command("useradd", "-M", "-N", "packets").Run() + + uid, err := GetPacketsUID() + if err != nil { + return err + } + + return syscall.Setresuid(0, uid, 0) + +} + +func ElevatePermission() error { return syscall.Setresuid(0, 0, 0) } diff --git a/pkg/main.go b/pkg/main.go index a89fb6f..5876ed2 100644 --- a/pkg/main.go +++ b/pkg/main.go @@ -6,6 +6,7 @@ import ( "io" "os" "packets/internal/utils" + "runtime" utils_lua "packets/internal/utils/lua" "path/filepath" @@ -31,6 +32,11 @@ func InstallPackage(file []byte, destDir string) error { tarReader := tar.NewReader(zstdReader) + uid, err := utils.GetPacketsUID() + if err != nil { + return err + } + for { hdr, err := tarReader.Next() if err == io.EOF { @@ -46,7 +52,11 @@ func InstallPackage(file []byte, destDir string) error { continue } - if err := os.MkdirAll(destDir, 0755); err != nil { + if err := os.MkdirAll(destDir, 0775); err != nil { + return err + } + + if err := os.Chown(destDir, uid, 0); err != nil { return err } @@ -56,13 +66,16 @@ func InstallPackage(file []byte, destDir string) error { case tar.TypeDir: err = os.MkdirAll(absPath, os.FileMode(hdr.Mode)) - if err != nil { return err } + if err := os.Chown(absPath, uid, 0); err != nil { + return err + } case tar.TypeReg: - err = os.MkdirAll(filepath.Dir(absPath), 0755) + + err = os.MkdirAll(filepath.Dir(absPath), 0775) if err != nil { return err } @@ -78,10 +91,21 @@ func InstallPackage(file []byte, destDir string) error { return err } - err = os.Chmod(absPath, os.FileMode(hdr.Mode)) + err = os.Chmod(absPath, os.FileMode(0775)) if err != nil { return err } + + if filepath.Base(hdr.Name) == "manifest.toml" || filepath.Base(hdr.Name) == manifest.Hooks.Install || filepath.Base(hdr.Name) == manifest.Hooks.Remove { + err = os.Chmod(absPath, os.FileMode(0755)) + if err != nil { + return err + } + } else { + if err := os.Chown(absPath, uid, 0); err != nil { + return err + } + } } } @@ -92,10 +116,20 @@ func InstallPackage(file []byte, destDir string) error { L.SetGlobal("data_dir", lua.LString(filepath.Join(destDir, "data"))) L.SetGlobal("script", lua.LString(manifest.Hooks.Install)) + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + if err := utils.ChangeToNoPermission(); err != nil { + return err + } if err := L.DoFile(filepath.Join(destDir, manifest.Hooks.Install)); err != nil { return err } + if err := utils.ElevatePermission(); err != nil { + return err + } + return nil } @@ -111,9 +145,20 @@ func ExecuteRemoveScript(path string) error { L.SetGlobal("script", lua.LString(path)) L.SetGlobal("build", lua.LNil) + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + if err := utils.ChangeToNoPermission(); err != nil { + return err + } + if err := L.DoFile(path); err != nil { return err } + if err := utils.ElevatePermission(); err != nil { + return err + } + return nil }