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
|
/*
* setup.go - File containing the functionality for initializing directories and
* the global config file.
*
* Copyright 2017 Google Inc.
* Author: Joe Richey (joerichey@google.com)
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package main
import (
"fmt"
"io"
"os"
"github.com/google/fscrypt/actions"
"github.com/google/fscrypt/filesystem"
"github.com/google/fscrypt/util"
)
// createGlobalConfig creates (or overwrites) the global config file
func createGlobalConfig(w io.Writer, path string) error {
if !util.IsUserRoot() {
return ErrMustBeRoot
}
// If the config file already exists, ask to replace it
_, err := os.Stat(path)
switch {
case err == nil:
err = askConfirmation(fmt.Sprintf("Replace %q?", path), false, "")
if err == nil {
err = os.Remove(path)
}
case os.IsNotExist(err):
err = nil
}
if err != nil {
return err
}
// v2 encryption policies are recommended, so set policy_version 2 when
// the kernel supports it. v2 policies are supported by upstream Linux
// v5.4 and later. For now we simply check the kernel version. Ideally
// we'd instead check whether setting a v2 policy actually works, in
// order to also detect backports of the kernel patches. However, that's
// hard because from this context (creating /etc/fscrypt.conf) we may
// not yet have access to a filesystem that supports encryption.
var policyVersion int64
if util.IsKernelVersionAtLeast(5, 4) {
fmt.Fprintln(w, "Defaulting to policy_version 2 because kernel supports it.")
policyVersion = 2
} else {
fmt.Fprintln(w, "Defaulting to policy_version 1 because kernel doesn't support v2.")
}
fmt.Fprintln(w, "Customizing passphrase hashing difficulty for this system...")
err = actions.CreateConfigFile(timeTargetFlag.Value, policyVersion)
if err != nil {
return err
}
fmt.Fprintf(w, "Created global config file at %q.\n", path)
return nil
}
// setupFilesystem creates the directories for a filesystem to use fscrypt.
func setupFilesystem(w io.Writer, path string) error {
ctx, err := actions.NewContextFromMountpoint(path, nil)
if err != nil {
return err
}
username := ctx.TargetUser.Username
err = ctx.Mount.CheckSetup()
if err == nil {
return &filesystem.ErrAlreadySetup{Mount: ctx.Mount}
}
if _, ok := err.(*filesystem.ErrNotSetup); !ok {
return err
}
allUsers := allUsersSetupFlag.Value
if !allUsers {
thisFilesystem := "this filesystem"
if ctx.Mount.Path == "/" {
thisFilesystem = "the root filesystem"
}
prompt := fmt.Sprintf(`Allow users other than %s to create
fscrypt metadata on %s? (See
https://github.com/google/fscrypt#setting-up-fscrypt-on-a-filesystem)`,
username, thisFilesystem)
allUsers, err = askQuestion(wrapText(prompt, 0), false)
if err != nil {
return err
}
}
var setupMode filesystem.SetupMode
if allUsers {
setupMode = filesystem.WorldWritable
} else {
setupMode = filesystem.SingleUserWritable
}
if err = ctx.Mount.Setup(setupMode); err != nil {
return err
}
if allUsers {
fmt.Fprintf(w, "Metadata directories created at %q, writable by everyone.\n",
ctx.Mount.BaseDir())
} else {
fmt.Fprintf(w, "Metadata directories created at %q, writable by %s only.\n",
ctx.Mount.BaseDir(), username)
}
return nil
}
|