Skip to content
Snippets Groups Projects
helpers.go 2.59 KiB
Newer Older
  • Learn to ignore specific revisions
  • Kali Kaneko's avatar
    Kali Kaneko committed
    // Copyright (C) 2020 LEAP
    //
    // This program is free software: you can redistribute it and/or modify
    // it under the terms of the GNU General Public License as published by
    // the Free Software Foundation, either version 3 of the License, or
    // (at your option) any later version.
    //
    // This program is distributed in the hope that it will be useful,
    // but WITHOUT ANY WARRANTY; without even the implied warranty of
    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    // GNU General Public License for more details.
    //
    // You should have received a copy of the GNU General Public License
    // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
    package pickle
    
    import (
    
    Kali Kaneko's avatar
    Kali Kaneko committed
    	"fmt"
    
    Kali Kaneko's avatar
    Kali Kaneko committed
    	"log"
    	"os"
    	"os/exec"
    
    	"runtime"
    
    //go:embed helpers
    var helpers embed.FS
    
    
    Kali Kaneko's avatar
    Kali Kaneko committed
    const (
    	bitmaskRoot = "/usr/sbin/bitmask-root"
    	// TODO parametrize this with config.appName
    	policyFile = "/usr/share/polkit-1/actions/se.leap.bitmask.riseupvpn.policy"
    )
    
    func check(e error) {
    	if e != nil {
    		panic(e)
    	}
    }
    
    func alreadyThere(path string) bool {
    	if _, err := os.Stat(path); err == nil {
    		return true
    	}
    	return false
    }
    
    
    func isRoot() bool {
    	uid := os.Getuid()
    	return uid == 0
    }
    
    
    Kali Kaneko's avatar
    Kali Kaneko committed
    func copyAsRoot(orig, dest string, isExec bool) {
    	if alreadyThere(dest) {
    		fmt.Println("> File exists: ", dest)
    		return
    	}
    
    
    	cmd := exec.Command("false")
    	if isRoot() {
    		cmd = exec.Command("cp", orig, dest)
    	} else {
    		var confirm string
    		fmt.Println("> About to write (with sudo):", dest)
    		fmt.Printf("> ok? [y/N] ")
    		fmt.Scanln(&confirm)
    		if confirm != "y" {
    			fmt.Println("aborting")
    			os.Exit(1)
    		}
    		cmd = exec.Command("sudo", "cp", orig, dest)
    
    Kali Kaneko's avatar
    Kali Kaneko committed
    	err := cmd.Run()
    	check(err)
    
    	if isExec {
    
    		if isRoot() {
    			cmd = exec.Command("chmod", "776", dest)
    		} else {
    			cmd = exec.Command("sudo", "chmod", "776", dest)
    		}
    
    Kali Kaneko's avatar
    Kali Kaneko committed
    		err = cmd.Run()
    		check(err)
    
    atanarjuat tfr's avatar
    atanarjuat tfr committed
    	} else {
    		if isRoot() {
    			cmd = exec.Command("chmod", "644", dest)
    		} else {
    			cmd = exec.Command("sudo", "chmod", "644", dest)
    		}
    		err = cmd.Run()
    		check(err)
    
    Kali Kaneko's avatar
    Kali Kaneko committed
    	}
    
    	fmt.Println("> done")
    }
    
    func dumpHelper(fname, dest string, isExec bool) {
    
    	// TODO win/mac implementation
    	if runtime.GOOS != "linux" {
    		fmt.Println("Only linux supported for now")
    		return
    	}
    
    	fd, err := helpers.Open(path.Join("helpers", fname))
    
    Kali Kaneko's avatar
    Kali Kaneko committed
    	if err != nil {
    		log.Fatal(err)
    	}
    
    
    	tmpfile, err := os.CreateTemp("/dev/shm", "*")
    
    Kali Kaneko's avatar
    Kali Kaneko committed
    	check(err)
    
    	defer os.Remove(tmpfile.Name())
    
    	_, err = io.Copy(tmpfile, fd)
    
    Kali Kaneko's avatar
    Kali Kaneko committed
    	check(err)
    
    	copyAsRoot(tmpfile.Name(), dest, isExec)
    
    Kali Kaneko's avatar
    Kali Kaneko committed
    }
    
    func InstallHelpers() {
    	dumpHelper("bitmask-root", bitmaskRoot, true)
    	dumpHelper("se.leap.bitmask.policy", policyFile, false)
    }