diff options
author | psyc://loupsycedyglgamf.onion/~lynX <BM-NB7xa9gEpmJgYp9PVnEdACiZcGmmEJcY> | 2016-08-28 22:14:12 +0000 |
---|---|---|
committer | psyc://loupsycedyglgamf.onion/~lynX <BM-NB7xa9gEpmJgYp9PVnEdACiZcGmmEJcY> | 2016-08-28 22:14:12 +0000 |
commit | 6f426bf0d5133d28ee553dda9623fbb1e5ee5be5 (patch) | |
tree | 4f77b68057aa63777c7ff0d430ffaebaf1f49321 /sys-fs | |
parent | c3a38834e285ab71b73d52cb90bb4342bf5f2034 (diff) | |
download | youbroketheinternet-overlay-6f426bf0d5133d28ee553dda9623fbb1e5ee5be5.tar.gz youbroketheinternet-overlay-6f426bf0d5133d28ee553dda9623fbb1e5ee5be5.zip |
a gift to the hackers: mp4cut, dmc and oneshot
Diffstat (limited to 'sys-fs')
-rw-r--r-- | sys-fs/dmc/dmc-1.0.ebuild | 19 | ||||
-rwxr-xr-x | sys-fs/dmc/files/dmc | 404 |
2 files changed, 423 insertions, 0 deletions
diff --git a/sys-fs/dmc/dmc-1.0.ebuild b/sys-fs/dmc/dmc-1.0.ebuild new file mode 100644 index 0000000..d2b2475 --- /dev/null +++ b/sys-fs/dmc/dmc-1.0.ebuild | |||
@@ -0,0 +1,19 @@ | |||
1 | # Distributed under the terms of the Affero GNU General Public License v2 | ||
2 | # $Id$ | ||
3 | |||
4 | EAPI=5 | ||
5 | |||
6 | DESCRIPTION="Command line UX frontend to dm-crypt's cryptsetup with support for multiple file systems" | ||
7 | |||
8 | LICENSE="AGPL" | ||
9 | SLOT="0" | ||
10 | KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86 ~amd64-fbsd ~sparc-fbsd ~x86-fbsd" | ||
11 | DEPEND="dev-lang/perl virtual/perl-Term-ANSIColor sys-fs/cryptsetup sys-apps/util-linux" | ||
12 | |||
13 | S="$WORKDIR" | ||
14 | |||
15 | src_install() { | ||
16 | exeinto /usr/sbin | ||
17 | doexe "${FILESDIR}"/${PN} | ||
18 | } | ||
19 | |||
diff --git a/sys-fs/dmc/files/dmc b/sys-fs/dmc/files/dmc new file mode 100755 index 0000000..b8cd710 --- /dev/null +++ b/sys-fs/dmc/files/dmc | |||
@@ -0,0 +1,404 @@ | |||
1 | #!/usr/bin/perl | ||
2 | # | ||
3 | # dm-crypt tool with vaguely similar command line syntax to truecrypt. | ||
4 | # simplifies management of volumes with LUKS and a file system inside. | ||
5 | # reasons to use LUKS instead of truecrypt are: you can resize file | ||
6 | # systems + dm-crypt behaves a bit more reliably when doing heavy duty | ||
7 | # storage transactions. there is nothing wrong with truecrypt's | ||
8 | # cryptography though! | ||
9 | # | ||
10 | # --vonlynX 2014, 2015 | ||
11 | # | ||
12 | # TODO: fallocate is cool. maybe we even want an option for 'truncate' | ||
13 | # aka using sparse files that factually get allocated on the fly? | ||
14 | |||
15 | use Term::ANSIColor qw(:constants); | ||
16 | |||
17 | use Getopt::Std; | ||
18 | getopt('tsump'); | ||
19 | # i liked 'sumpf' but it was not worth renaming -t into -f | ||
20 | |||
21 | # urandom is rather slow, zero is faster. by default however we use | ||
22 | # 'fallocate' instead of 'dd' which reserves an amount of disk space | ||
23 | # for the volume without changing it at all, which can be considered | ||
24 | # as slightly disguising. better and much faster than zeroing it out. | ||
25 | sub RND () { 'if=/dev/' . ($opt_R? 'urandom': 'zero') } | ||
26 | # remember that this is only relevant if you don't plan to fill the | ||
27 | # volume up completely - random bytes hide how much of the container | ||
28 | # has been used. if you're likely to fill the entire space anyway, | ||
29 | # you might aswell start with a zeroed or fallocated container. | ||
30 | |||
31 | # should i need to access my volumes from microsoft or macos i'd | ||
32 | # rather install ext4 on them than pick an awful "compatible" fs. | ||
33 | sub FS () { 'ext4' } | ||
34 | |||
35 | sub debug () { 0 } | ||
36 | |||
37 | # we use undeclared global variables. that's the privilege of using | ||
38 | # a rapid prototyping and scripting language and to be respected. | ||
39 | $vol = shift; | ||
40 | $mnt = shift; | ||
41 | |||
42 | if ($opt_d and not $vol) { | ||
43 | # blkid shows the proper dmc mapper device even if | ||
44 | # the file system was mounted by its /dev/dm-# path | ||
45 | open(M, '/sbin/blkid |') or die "blkid: $!"; | ||
46 | &findmounts; | ||
47 | # under sane conditions these should already be | ||
48 | # updated, but conditions are sometimes insane | ||
49 | # my 4.0.x kernel just panicked on dmc -d | ||
50 | &findmounts if open(M, '/proc/self/mounts'); | ||
51 | &findmounts if open(M, '/etc/mtab'); | ||
52 | exit $!; | ||
53 | } | ||
54 | |||
55 | my $keef = undef; | ||
56 | my $fs = FS; | ||
57 | # just in case i use -f instead of -t | ||
58 | ($vol and not $opt_f) or die <<X; | ||
59 | |||
60 | Usage of $0: | ||
61 | |||
62 | dmc <volume> [<mountpath>] # mount a volume | ||
63 | dmc -d # dismount all dmc volumes | ||
64 | dmc -d <volume> [<mountpath>] # dismount a volume by filename | ||
65 | dmc -d <mapper> [<mountpath>] # dismount a volume by mapper name | ||
66 | dmc -c <volume> [<mountpath>] # format and mount an existing volume | ||
67 | dmc -cs <size> <volume> [<mountpath>] # create a volume of given size | ||
68 | dmc -es <size> <volume> [<mountpath>] # enlarge a volume by given size | ||
69 | dmc -e <volume> [<mountpath>] # adapt fs to a manually resized volume | ||
70 | dmc [-A|-C|-D] <volume> # add, change or delete a password | ||
71 | dmc -L <volume> # list key slots and show status | ||
72 | dmc -E <volume> # erase some or all passwords and keys | ||
73 | |||
74 | <size> may end in M for megabytes, G for gigabytes, T for terabytes... | ||
75 | If <mountpath> is omitted, /dev/shm/<mapper> is created instead. | ||
76 | Combining action flags such as -c, -e and -d produces unuseful effects. | ||
77 | |||
78 | Options: | ||
79 | -R # use /dev/urandom for volume creation (slow, but | ||
80 | # hides the amount of data stored in the volume) | ||
81 | -t <fstype> # use other file system type than $fs (only needed with -c) | ||
82 | -u <name> # specify user to chown file system to | ||
83 | -m <name> # use this specific mapper nickname | ||
84 | -n # no operation, just pretend | ||
85 | -q # quiet, do not show commands to be executed | ||
86 | |||
87 | X | ||
88 | |||
89 | ## HELPERS | ||
90 | |||
91 | sub sys2 { | ||
92 | print BOLD, BLUE, join(' ', @_), "\n", RESET unless $opt_q; | ||
93 | return system(@_) unless $opt_n; | ||
94 | } | ||
95 | sub sys { | ||
96 | print BOLD, GREEN, join(' ', @_), "\n", RESET unless $opt_q; | ||
97 | if (!$opt_n and system(@_)) { | ||
98 | if ($? == -1) { | ||
99 | print "\t{failed to execute: $!}\n"; | ||
100 | } elsif ($? & 127) { | ||
101 | printf "\t{command died with sig %d, %s core dump}\n", | ||
102 | ($? & 127), ($? & 128) ? 'with' : 'without'; | ||
103 | } else { | ||
104 | printf "\t{command exited with value %d}\n", $? >> 8; | ||
105 | } | ||
106 | exit $? if $?; | ||
107 | exit $@ if $@; | ||
108 | } | ||
109 | } | ||
110 | sub prepare { | ||
111 | unless ($nick = $opt_m) { | ||
112 | $nick = $vol; | ||
113 | $nick =~ s/\.\w+$//; # remove a trailing extension | ||
114 | $nick = $1 if $nick =~ /(\w+)$/; # use last word of volume name | ||
115 | } | ||
116 | |||
117 | if (not $opt_d and -e $mapper) { | ||
118 | srand; | ||
119 | $r = int(rand(100)); | ||
120 | warn <<X; | ||
121 | Warning: $mapper already exists, using $mapper$r instead | ||
122 | X | ||
123 | $mapper = $mapper . $r; | ||
124 | $map = $map . $r; | ||
125 | $nick = $nick . $r; | ||
126 | } | ||
127 | |||
128 | # /media is a good idea because the desktop environments will show | ||
129 | # device icons for it and make it easy to use for GUI users. | ||
130 | # unfortunately it stops the automounter from doing its job. why? | ||
131 | if ( -w "/dev/shm" ) { | ||
132 | $media = "/dev/shm"; | ||
133 | } else { | ||
134 | $media = "/tmp"; | ||
135 | } | ||
136 | $mnt = "$media/$nick" unless $mnt; | ||
137 | |||
138 | # the prefix is useful to automate dismounting of all dmcs | ||
139 | $map = "dmc-$nick"; | ||
140 | $mapper = "/dev/mapper/$map"; | ||
141 | } | ||
142 | sub unmount { | ||
143 | if ($opt_n or -r $mapper) { | ||
144 | sys2 '/bin/umount', $mnt; # ignore if already unmounted | ||
145 | sys2 '/sbin/cryptsetup', 'luksClose', $map; | ||
146 | sys2 '/bin/rmdir', $mnt; | ||
147 | } else { | ||
148 | print "\t{$mapper already dismounted}\n"; | ||
149 | } | ||
150 | } | ||
151 | my %unmounted = {}; | ||
152 | sub findmounts { | ||
153 | while (<M>) { | ||
154 | # this matches either input format | ||
155 | if (m!^/dev/mapper/dmc-(\S+?):? !) { | ||
156 | $vol = $1; | ||
157 | next if $unmounted{$vol}; | ||
158 | undef $mnt; | ||
159 | &prepare; | ||
160 | &unmount; | ||
161 | ++$unmounted{$vol}; | ||
162 | } | ||
163 | } | ||
164 | close M; | ||
165 | } | ||
166 | sub luksDump { | ||
167 | sys '/sbin/cryptsetup', 'luksDump', $vol; | ||
168 | print "\n"; | ||
169 | } | ||
170 | sub wordFetch { | ||
171 | my $f = shift; | ||
172 | print "{found key in $f}\n" if debug; | ||
173 | $keef = $f; | ||
174 | # double braces allow me to use 'next' locally | ||
175 | if (open (F, $f)) {{ | ||
176 | $_ = <F>; | ||
177 | close F; | ||
178 | die if length() < 2; | ||
179 | next unless s/\s+$//; | ||
180 | open (F, ">$f") or | ||
181 | die "Cannot fix trailing whitespace in $f"; | ||
182 | print F $_; | ||
183 | close F; | ||
184 | print "{fixed trailing whitespace in $f}\n"; | ||
185 | }} | ||
186 | return 1; | ||
187 | } | ||
188 | |||
189 | ## MAIN | ||
190 | |||
191 | |||
192 | &prepare; | ||
193 | |||
194 | die <<X if $nick =~ m:/:; | ||
195 | |||
196 | Invalid volume name. $0 needs volume names to end | ||
197 | in a word character string <name> or <name>.<extension> | ||
198 | |||
199 | X | ||
200 | |||
201 | if (opendir D, $media) { | ||
202 | while (readdir D) { | ||
203 | my $p = "$media/$_"; | ||
204 | # this also checks . and .. | ||
205 | # but is that a problem? | ||
206 | next unless -d $p; | ||
207 | my $f = "$p/.words/$nick"; | ||
208 | print "{looking for key in $f}\n" if debug; | ||
209 | next unless -r $f; | ||
210 | last if &wordFetch($f); | ||
211 | } | ||
212 | closedir D; | ||
213 | } | ||
214 | unless ($keef) { | ||
215 | my $f = "/root/.words/$nick"; | ||
216 | &wordFetch($f) if -r $f; | ||
217 | } | ||
218 | |||
219 | $user = $opt_u || $ENV{SUDO_USER}; | ||
220 | |||
221 | if ($opt_d) { | ||
222 | &unmount; | ||
223 | exit; | ||
224 | } | ||
225 | |||
226 | if ($opt_L) { | ||
227 | &luksDump; | ||
228 | goto ADEU; | ||
229 | } | ||
230 | if ($opt_A) { | ||
231 | &luksDump; | ||
232 | sys '/sbin/cryptsetup', 'luksAddKey', '--key-file', $keef, $vol if $keef; | ||
233 | sys '/sbin/cryptsetup', 'luksAddKey', $vol unless $keef; | ||
234 | &luksDump; | ||
235 | exit; | ||
236 | } | ||
237 | if ($opt_C) { | ||
238 | &luksDump; | ||
239 | sys '/sbin/cryptsetup', 'luksChangeKey', '--key-file', $keef, $vol if $keef; | ||
240 | sys '/sbin/cryptsetup', 'luksChangeKey', $vol unless $keef; | ||
241 | &luksDump; | ||
242 | exit; | ||
243 | } | ||
244 | if ($opt_D) { | ||
245 | &luksDump; | ||
246 | # Ignoring $keef for this one... as it might happen by mistake | ||
247 | sys '/sbin/cryptsetup', 'luksRemoveKey', $vol; | ||
248 | &luksDump; | ||
249 | exit; | ||
250 | } | ||
251 | if ($opt_E) { | ||
252 | &luksDump; | ||
253 | print <<X; | ||
254 | |||
255 | If you really want to remove all access keys and make the | ||
256 | volume inaccessible, copy and paste this command: | ||
257 | |||
258 | /sbin/cryptsetup erase $vol | ||
259 | /bin/rm $vol | ||
260 | |||
261 | If you need to remove a certain key slot but leave the | ||
262 | others as they are, here's what you need: | ||
263 | |||
264 | /sbin/cryptsetup luksKillSlot $vol <slot-number> | ||
265 | |||
266 | X | ||
267 | exit; | ||
268 | } | ||
269 | |||
270 | if ($opt_s) { | ||
271 | $size = $opt_s; | ||
272 | $unit = uc($1) if $size =~ s/(\w)$//i; | ||
273 | $size = 1024 * $size if $unit eq 'K'; | ||
274 | $size = 1024 * 1024 * $size if $unit eq 'M'; | ||
275 | $size = 1024 * 1024 * 1024 * $size if $unit eq 'G'; | ||
276 | $size = 1024 * 1024 * 1024 * 1024 * $size if $unit eq 'T'; | ||
277 | |||
278 | # let's use a megabyte large buffer | ||
279 | $unit = "bs=1M"; | ||
280 | $size = $size / (1024 * 1024); | ||
281 | $size = "count=$size" if $size; | ||
282 | } | ||
283 | |||
284 | if ($size and $opt_e) { | ||
285 | die "$vol doesn't exist. Did you mean -c instead of -e? " unless -e $vol; | ||
286 | # frequent use case, enlarge a currently mounted volume | ||
287 | &unmount; | ||
288 | # fallocate does not respect -R requirements... | ||
289 | if ($opt_R or sys2 '/usr/bin/fallocate', '-o', -s $vol, '-l', $opt_s, $vol) { | ||
290 | print "Reverting to 'dd' ...\n" unless $opt_R; | ||
291 | sys '/bin/dd', 'oflag=append', 'conv=notrunc', RND, $unit, | ||
292 | $size, "of=$vol"; | ||
293 | } | ||
294 | # otherwise assume the user has resized the volume manually | ||
295 | } elsif ($opt_c) { | ||
296 | # not sure about auto-unmount here | ||
297 | if ($size) { | ||
298 | die "$vol already exists. Did you mean -e instead of -c? " if -e $vol; | ||
299 | if ($opt_R or sys2 '/usr/bin/fallocate', '-l', $opt_s, $vol) { | ||
300 | print "Reverting to 'dd' ...\n" unless $opt_R; | ||
301 | sys '/bin/dd', RND, $unit, $size, "of=$vol"; | ||
302 | } | ||
303 | } | ||
304 | sys '/sbin/cryptsetup', 'luksFormat', '--batch-mode', $vol, $keef if $keef; | ||
305 | sys '/sbin/cryptsetup', 'luksFormat', '--batch-mode', $vol unless $keef; | ||
306 | } elsif ($size) { | ||
307 | die <<X; | ||
308 | |||
309 | Option -s is cool but you have to choose between -c and -e to go with it. | ||
310 | |||
311 | X | ||
312 | } | ||
313 | |||
314 | if ($opt_p) { | ||
315 | # ugly, do not use | ||
316 | sys "/bin/echo -n '$opt_p' | /sbin/cryptsetup luksOpen --key-file - '$vol' '$map'"; | ||
317 | } elsif ($keef) { | ||
318 | sys "/sbin/cryptsetup luksOpen --key-file '$keef' '$vol' '$map'"; | ||
319 | } else { | ||
320 | sys '/sbin/cryptsetup', 'luksOpen', $vol, $map; | ||
321 | } | ||
322 | |||
323 | if ($opt_c) { | ||
324 | $fs = $opt_t || FS; | ||
325 | # so logical that each file system had to have its own | ||
326 | # mkfs flag to pass the device label name.. right? | ||
327 | if ( $fs =~ /^ext/ ) { | ||
328 | # optimizations of ext* filesystems depending on size happens | ||
329 | # automatically as defined in /etc/mke2fs.conf | ||
330 | sys '/sbin/mkfs.'. $fs, '-m', '0', '-L', $nick, $mapper; | ||
331 | # -m is the percentage of root-reserved blocks. only makes sense | ||
332 | # for file systems in production use (system, server etc) | ||
333 | } elsif ($fs eq 'btrfs') { | ||
334 | sys '/sbin/mkfs.'. $fs, '-L', $nick, $mapper; | ||
335 | } elsif ($fs eq 'ntfs') { | ||
336 | # zeroing out a virtual volume is silly: Q for quick | ||
337 | sys '/sbin/mkfs.'. $fs, '-QIL', $nick, $mapper; | ||
338 | # I disables content indexing | ||
339 | } elsif ($fs eq 'reiserfs') { | ||
340 | sys '/sbin/mkfs.'. $fs, '-l', $nick, $mapper; | ||
341 | } elsif ($fs eq 'bfs') { | ||
342 | sys '/sbin/mkfs.'. $fs, '-V', $nick, $mapper; | ||
343 | } elsif ($fs eq 'minix') { | ||
344 | sys '/sbin/mkfs.minix', $mapper; | ||
345 | } else { # msdos, fat, vfat | ||
346 | sys '/sbin/mkfs.'. $fs, '-n', $nick, $mapper; | ||
347 | } | ||
348 | } else { | ||
349 | open(B, '-|', '/sbin/blkid', $mapper) or die "blkid: $!"; | ||
350 | $_ = <B>; | ||
351 | $fs = $1 if / TYPE="(\w+)"/; | ||
352 | close B; | ||
353 | die "Could not detect filesystem of $mapper" unless $fs or $opt_n; | ||
354 | } | ||
355 | |||
356 | if ($opt_e) { | ||
357 | sys '/sbin/cryptsetup', 'resize', $mapper; | ||
358 | # so reasonable there is no fs-independent resize command! | ||
359 | # hey wait.. there is a shell script called fsadm that knows | ||
360 | # half of the file systems.. but not the ones i need. great! | ||
361 | if ($fs eq 'ntfs') { | ||
362 | sys '/usr/sbin/ntfsresize', $mapper; | ||
363 | } elsif ($fs eq 'btrfs') { | ||
364 | # btrfs needs it AFTER mounting! | ||
365 | } elsif ($fs eq 'xfs') { | ||
366 | # xfs cannot be shrunk! | ||
367 | sys '/usr/sbin/xfs_growfs', $mapper; | ||
368 | } elsif ($fs eq 'reiserfs') { | ||
369 | sys '/usr/sbin/resize_reiserfs', $mapper; | ||
370 | } else { | ||
371 | sys2 '/sbin/fsck', '-f', $mapper; | ||
372 | # sys '/sbin/resize2fs', $mapper; | ||
373 | sys '/sbin/fsadm', 'resize', $mapper; | ||
374 | } | ||
375 | } | ||
376 | |||
377 | sys2 '/bin/mkdir', '-p', $mnt unless -d $mnt; | ||
378 | |||
379 | chdir ('/'); # nothing as annoying as having mounted A in dependency of B | ||
380 | |||
381 | if ($fs eq 'ntfs') { | ||
382 | sys '/bin/mount', '-v', '-t', $fs, $mapper, $mnt; | ||
383 | } else { | ||
384 | unless ($opt_c or $opt_e) { | ||
385 | # would have spared me a system crash recently... | ||
386 | sys2 '/sbin/fsck', $mapper if $fs ne 'btrfs'; | ||
387 | # fsck returns 1 even if it just created lost+found | ||
388 | # so we'll ignore the return code. trying to mount it | ||
389 | # will be the next thing we want to do anyhow | ||
390 | # | ||
391 | #sys2 '/sbin/btrfs', 'check', $mapper if $fs eq 'btrfs'; | ||
392 | # madness. btrfs check takes ages and cannot be sped up. | ||
393 | } | ||
394 | sys '/bin/mount', $mapper, $mnt; | ||
395 | } | ||
396 | |||
397 | sys2 "/sbin/btrfs filesystem resize max $mnt" if $opt_e and $fs eq 'btrfs'; | ||
398 | sys '/bin/chown', $user, $mnt if $opt_c and $user; | ||
399 | |||
400 | ADEU: | ||
401 | |||
402 | sys2 '/sbin/cryptsetup', 'status', $mapper unless $opt_q; | ||
403 | sys '/bin/df', '-Th', $mnt if -d $mnt; | ||
404 | |||