OpenSANd Code
Brought to you by:
hoefer
#! /usr/bin/perl
# This is opensand, an NBD base SAN system
# Copyright (C) 2008-2014 Stefan Hoefer <stefan@hoefer.ch>
#
# 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/>.
# This tool will manually encrypt a disk (by asking for a password).
# Disks may only be manually encrypted, if they are
#
# * not active
# * not otherwise encrypted
#
# As soon as the disk is connected and disconnected again, the
# encryption will be gone! Short interruptions (nbdproxy) will
# most probably at least partially destroy the contents of the
# disk as soon as subsequent write calls arrive after a reconnect!
use strict;
use utf8;
use POSIX;
if (getuid() != 0) {
die "You must be root to run this!\n";
}
my $diskid = $ARGV[0];
if (!defined($diskid)) {
die "Usage: osscramble <diskid>\n";
}
if ($diskid !~ /^[0-9]+$/ || $diskid > 500) {
die "A valid diskid must be a number between 0 and 500!\n";
}
if (!disk_exists($diskid)) {
die "No such disk\n";
}
if (is_active($diskid)) {
die "The disk is active, cannot manually encrypt\n";
}
if (is_encrypted($diskid)) {
die "The disk is encrypted by configuration, cannot manually encrypt\n";
}
if (encryption_active($diskid)) {
print "Manual encryption already active, cannot encrypt again.\n";
print "To disable manual encryption, use\n\n";
print " oscontrol scramble $diskid 0\n";
exit(0);
}
print STDERR "Going to scramble disk $diskid\n";
print STDERR "CAREFUL: the passphrase input will be prompted (but not logged)!\n";
print STDERR "The passphrase must be at least 32 characters long.\n";
print STDERR "Hit Ctrl-C now if you want to abort.\n";
print STDERR "Please enter the passphrase: ";
my $input = <STDIN>;
chomp $input;
if (length($input) < 32) {
die "Passphrase too short!\n";
}
encrypt_disk($diskid, $input);
sub disk_exists {
my $diskid = shift;
my $diskpath = disk_path($diskid);
if (-e $diskpath) {
return 1;
}
else {
return 0;
}
}
sub encrypt_disk {
my $diskid = shift;
my $passphrase = shift;
my $linkpath = link_path($diskid);
if (-l $linkpath) {
unlink($linkpath);
}
my $encryptedname = encrypted_name($diskid);
my $diskpath = disk_path($diskid);
my $fd;
if (open($fd, "| cryptsetup create $encryptedname -c aes -s 256 $diskpath")) {
print $fd $passphrase;
close($fd);
if ($?) {
die "Error while encrypting the disk: $?!\n";
}
my $encryptedpath = encrypted_disk_path($diskid);
if (!symlink($encryptedpath, $linkpath)) {
die "Error while creating symlink!\n";
}
}
else {
die "Error while executing cryptsetup: $?\n";
}
}
sub encrypted_name {
my $diskid = shift;
my $name = sprintf("opensand_disk_%05d", $diskid);
return $name;
}
sub disk_name {
my $diskid = shift;
my $name = sprintf("lv_disk%05d", $diskid);
return $name;
}
sub encryption_active {
my $diskid = shift;
my $encryptedpath = encrypted_disk_path($diskid);
if (-l $encryptedpath) {
return 1;
}
else {
return 0;
}
}
sub is_active {
my $diskid = shift;
my $diskpath = disk_path($diskid);
my $attrs = `lvs --noheadings -o lv_attr $diskpath`;
chomp $attrs;
if ($attrs !~ /^ +.....-/) {
return 1;
}
else {
return 0;
}
}
sub is_encrypted {
my $diskid = shift;
my $path = sprintf("/var/lib/opensand/encryption/disk%05d", $diskid);
if (-e $path) {
return 1;
}
else {
return 0;
}
}
sub disk_path {
my $diskid = shift;
my $diskname = disk_name($diskid);
return "/dev/vg_opensand/$diskname";
}
sub encrypted_disk_path {
my $diskid = shift;
my $encryptedname = encrypted_name($diskid);
return "/dev/mapper/$encryptedname";
}
sub link_path {
my $diskid = shift;
my $path = sprintf("/var/lib/opensand/disks/disk%05d", $diskid);
return $path;
}