Mercurial > go > multipass
annotate file/file.go @ 0:c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Sat, 24 Oct 2015 21:32:03 -0400 |
parents | |
children | e58bfc7fc207 |
rev | line source |
---|---|
0
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
1 // Package file handles I/O for single password files. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
2 // |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
3 // A password file contains multiple passwords for a single user. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
4 // It starts with a banner that indicates the version of the file, |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
5 // then has entries in the format specified by auth.Entry. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
6 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
7 package file |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
8 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
9 import ( |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
10 "bufio" |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
11 "errors" |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
12 "os" |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
13 "os/user" |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
14 "syscall" |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
15 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
16 "path" |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
17 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
18 "golang.org/x/sys/unix" |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
19 "pfish.zone/go/multipass/auth" |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
20 ) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
21 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
22 const ( |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
23 // the Banner acts as a version indicator |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
24 Banner = "# Multipass v0.1 password file" |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
25 ) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
26 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
27 var ( |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
28 // Raised when |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
29 ErrorBadFile = errors.New("multipass/file: Invalid file format") |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
30 ) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
31 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
32 type ShadowFile struct { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
33 name string |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
34 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
35 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
36 // ForUser gets the given user's ShadowFile. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
37 func ForUser(username string) (*ShadowFile, error) { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
38 u, err := user.Lookup(username) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
39 if err != nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
40 return nil, err |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
41 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
42 return New(path.Join(u.HomeDir, MultipassFile)), nil |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
43 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
44 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
45 // ForMe gets the current user's ShadowFile. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
46 func ForMe() (*ShadowFile, error) { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
47 u, err := user.Current() |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
48 if err != nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
49 return nil, err |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
50 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
51 return New(path.Join(u.HomeDir, MultipassFile)), nil |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
52 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
53 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
54 // New creates a ShadowFile for reading at the given path. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
55 // If a file needs to be created, uses the given GID to create it. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
56 func New(name string) *ShadowFile { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
57 f := new(ShadowFile) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
58 f.name = name |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
59 return f |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
60 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
61 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
62 func (f *ShadowFile) newFilename() string { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
63 return f.name + ".new" |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
64 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
65 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
66 func (f *ShadowFile) open() (*os.File, *bufio.Scanner, error) { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
67 file, err := os.Open(f.name) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
68 if err != nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
69 return nil, nil, err |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
70 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
71 scanner := bufio.NewScanner(file) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
72 if !scanner.Scan() { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
73 file.Close() |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
74 return nil, nil, err |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
75 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
76 if scanner.Text() != Banner { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
77 file.Close() |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
78 return nil, nil, ErrorBadFile |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
79 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
80 return file, scanner, nil |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
81 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
82 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
83 func (f *ShadowFile) Authenticate(password string) (bool, error) { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
84 file, scanner, err := f.open() |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
85 if err != nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
86 return false, err |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
87 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
88 defer file.Close() |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
89 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
90 for scanner.Scan() { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
91 entry, err := auth.EntryFromShadow(scanner.Text()) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
92 // Skip invalid lines. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
93 if err != nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
94 continue |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
95 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
96 if entry.Authenticate(password) { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
97 return true, nil |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
98 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
99 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
100 return false, nil |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
101 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
102 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
103 func (f *ShadowFile) Add(entry *auth.Entry) error { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
104 handle, err := f.openWrite() |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
105 if err != nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
106 return err |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
107 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
108 err = handle.write(entry) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
109 if err != nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
110 handle.bail() |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
111 return err |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
112 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
113 for handle.next() { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
114 if entry, err := handle.entry(); err == nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
115 // If we get an invalid entry, just skip it. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
116 if err := handle.write(entry); err != nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
117 handle.bail() |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
118 return err |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
119 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
120 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
121 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
122 return handle.finalize() |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
123 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
124 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
125 func (f *ShadowFile) openWrite() (*writeHandle, error) { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
126 return openWriteHandle(f.newFilename(), f.name) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
127 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
128 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
129 type writeHandle struct { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
130 // We write to a file handle pointing to tempName. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
131 tempName string |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
132 tempFile *os.File |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
133 writer *bufio.Writer |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
134 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
135 // It will eventually move to fileName, which is our source file. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
136 fileName string |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
137 // If inFile is nil, we're creating a new multipass file. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
138 inFile *os.File |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
139 scanner *bufio.Scanner |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
140 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
141 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
142 func openWriteHandle(tempName, fileName string) (*writeHandle, error) { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
143 h := new(writeHandle) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
144 h.tempName = tempName |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
145 h.fileName = fileName |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
146 // Open the output file, readable only by the current user. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
147 oldUmask := unix.Umask(077) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
148 tempFile, err := os.Create(tempName) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
149 unix.Umask(oldUmask) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
150 if err != nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
151 return nil, err |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
152 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
153 h.tempFile = tempFile |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
154 // Open the input file. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
155 inFile, err := os.Open(fileName) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
156 if err == nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
157 // Prepare to read in the input file, if it exists. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
158 h.inFile = inFile |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
159 h.scanner = bufio.NewScanner(h.inFile) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
160 if !h.scanner.Scan() { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
161 return nil, ErrorBadFile |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
162 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
163 if h.scanner.Text() != Banner { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
164 return nil, ErrorBadFile |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
165 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
166 // Change the owner and group of the new file to that of the old. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
167 inStat, err := h.inFile.Stat() |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
168 if err != nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
169 h.bail() |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
170 return nil, err |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
171 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
172 inStatUnix := inStat.Sys().(*syscall.Stat_t) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
173 if err := h.tempFile.Chown(int(inStatUnix.Uid), int(inStatUnix.Gid)); err != nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
174 h.bail() |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
175 return nil, err |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
176 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
177 if err := h.tempFile.Chmod(inStat.Mode()); err != nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
178 h.bail() |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
179 return nil, err |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
180 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
181 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
182 // TODO(pfish): If there is no input file, set the right permissions + group on the output file. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
183 h.writer = bufio.NewWriter(h.tempFile) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
184 if _, err := h.writer.WriteString(Banner + "\n"); err != nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
185 return nil, err |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
186 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
187 return h, nil |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
188 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
189 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
190 func (h *writeHandle) bail() { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
191 h.tempFile.Close() |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
192 h.inFile.Close() |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
193 os.Remove(h.tempName) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
194 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
195 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
196 func (h *writeHandle) next() bool { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
197 // If the scanner is nil, then we have no input file and therefore no next. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
198 return h.scanner != nil && h.scanner.Scan() |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
199 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
200 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
201 func (h *writeHandle) entry() (*auth.Entry, error) { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
202 return auth.EntryFromShadow(h.scanner.Text()) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
203 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
204 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
205 func (h *writeHandle) write(entry *auth.Entry) error { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
206 if _, err := h.writer.WriteString(entry.Encode()); err != nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
207 return err |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
208 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
209 _, err := h.writer.WriteString("\n") |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
210 return err |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
211 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
212 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
213 func (h *writeHandle) finalize() error { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
214 h.inFile.Close() |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
215 // Make absolutely completely sure we're synced. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
216 if err := h.writer.Flush(); err != nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
217 h.tempFile.Close() |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
218 os.Remove(h.tempName) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
219 return err |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
220 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
221 if err := h.tempFile.Sync(); err != nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
222 h.tempFile.Close() |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
223 os.Remove(h.tempName) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
224 return err |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
225 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
226 // Close the file. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
227 if err := h.tempFile.Close(); err != nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
228 os.Remove(h.tempName) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
229 return err |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
230 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
231 // And atomically write it over the new one. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
232 err := os.Rename(h.tempName, h.fileName) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
233 if err != nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
234 return err |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
235 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
236 // If we get here, everything succeeded, and only in this case |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
237 // will the multipass shadow file have been updated. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
238 return nil |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
239 } |