-
Notifications
You must be signed in to change notification settings - Fork 4
/
main.go
131 lines (115 loc) · 3.29 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package main
import (
"crypto/rand"
"encoding/base32"
"errors"
"fmt"
"os"
"os/exec"
"path"
"regexp"
"strconv"
"github.com/golang/glog"
)
const (
ramdisk_uri = "ram://2048"
)
func randomBytes(c int) (b []byte, err error) {
if err != nil {
return b, err
}
return b, nil
}
func createPinnedRamdisk() (disk string, err error) {
// Creating an in-kernel ramdisk supposedly ensures that the memory
// is pinned; see man 1 hdiutil.
// TODO: Why doesn't encryption work with ramdisks? "-encryption", enckey,
hdik := exec.Command("/usr/sbin/hdik", "-nomount", ramdisk_uri)
out, err := hdik.CombinedOutput()
if err != nil {
return "", fmt.Errorf("hdik error: %s\n%s", err, out)
}
ramdiskre, _ := regexp.Compile("/dev/disk[0-9]+")
ramdisk := ramdiskre.Find(out)
if ramdisk == nil {
return "", fmt.Errorf("hdik didn't return a disk; output:\n %s", out)
}
return string(ramdisk), nil
}
func createFs(ramdisk string, uid int) (volname string, err error) {
// Generate a random volume name.
b := make([]byte, 20)
_, err = rand.Read(b)
if err != nil {
return "", errors.New("couldn't generate random volume name")
}
volname = base32.StdEncoding.EncodeToString(b) + ".noindex"
// Create the new filesystem
// -P: set kHFSContentProtectionBit
// -M 700: default mode=700
// (newfs_hfs is relatively safe; it won't unmount and erase a mounted disk)
newfs := exec.Command("/sbin/newfs_hfs", "-v", volname, "-U", strconv.Itoa(uid), "-G", "admin", "-M", "700", "-P", ramdisk)
out, err := newfs.CombinedOutput()
if err != nil {
return "", fmt.Errorf("newfs_hfs error: %s", out)
}
return volname, nil
}
func main() {
// Parse flags for glog
//flag.Parse()
uid := os.Getuid()
// Check that the current directory is owned by the real uid.
fi, err := os.Lstat(".")
if err != nil {
glog.Errorf("Error statting current directory: %s", err)
os.Exit(255)
}
if !fi.IsDir() {
// TODO: check ownership and go-rw
glog.Errorf("Current directory not a directory.")
os.Exit(255)
}
// Create the ramdisk
ramdisk, err := createPinnedRamdisk()
if err != nil {
glog.Errorf("createPinnedRamdisk: %s", err)
os.Exit(255)
}
// Create the filesystem
volname, err := createFs(ramdisk, uid)
if err != nil {
glog.Errorf("createFs: %s", err)
os.Exit(255)
}
// Create the mountpoint
mountpoint := path.Join("./", volname)
err = os.Mkdir(mountpoint, 700)
if err != nil {
glog.Errorf("couldn't create directory: %s", err)
os.Exit(255)
}
err = os.Lchown(mountpoint, uid, -1)
if err != nil {
glog.Errorf("couldn't chown directory: %s", err)
os.Exit(255)
}
// Mount the new volume on the mountpoint
mount := exec.Command("/sbin/mount_hfs", "-u", strconv.Itoa(uid), "-m", "700", "-o", "noatime,nosuid,nobrowse", ramdisk, string(mountpoint))
out, err := mount.CombinedOutput()
if err != nil {
glog.Errorf("couldn't mount new volume: %s\n%s", err, out)
os.Exit(255)
}
glog.Infof("mount_hfs: %s", out)
err = chprivDir(string(mountpoint), fmt.Sprintf("%d", uid))
if err != nil {
glog.Errorf("coudn't make dir safe\n%s", err)
// TODO: should this cause a non-zero exit status?
}
// TODO: disable indexing, trash, and fsevents; probably
// can drop privileges first
// rm -rf .fseventsd .Trashes
// touch .fseventsd/no_log .metadata_never_index .Trashes
fmt.Printf("%s\n%s", ramdisk, mountpoint)
}