[go: up one dir, main page]

Menu

[r20]: / trunk / osscramble  Maximize  Restore  History

Download this file

212 lines (157 with data), 4.4 kB

#! /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;
}