#!/usr/bin/perl

delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
$ENV{'PATH'}='/bin:/usr/bin:/sbin:/usr/sbin/';

$BASH=untaint(`which bash`);
$RM=untaint(`which rm`);
$MKTEMP=untaint(`which mktemp`);
$GUESTFISH=untaint(`which guestfish`);

# check binaries
if (!-x $GUESTFISH) {
    print STDERR "add_key cannot find all required binaries\n";
    exit(1);
}

# check input params
$mounter = untaint(shift @ARGV);
$offset = untaint(shift @ARGV);
$img = untaint(shift @ARGV);
$key = shift @ARGV; # untaint later

# without a key, add_key.pl just runs tune2fs
if (not defined($key)) {
    exit(0);
}

$key = untaint($key);
if (!-f "$key") {
    print STDERR "add_key cannot verify inputs: key=$key\n";
    exit(1);
}

# prepare guestfish script
$tmp = untaint(`$MKTEMP`);
open (SCRIPT, ">$tmp");
print SCRIPT "guestfish <<_EOF_\n";
print SCRIPT "add $img\n";
print SCRIPT "run\n";
print SCRIPT "mount /dev/vda1 /\n";
print SCRIPT "mkdir-p /root/.ssh\n";
print SCRIPT "upload $key /root/.ssh/authorized_keys\n";
print SCRIPT "chmod 0700 /root/.ssh\n";
print SCRIPT "chmod 0600 /root/.ssh/authorized_keys\n";
print SCRIPT "_EOF_\n";
close (SCRIPT);

# execute script
system("$BASH $tmp");

# remove script
system("$RM -rf $tmp");

sub untaint() {
    $str = shift;
    if ($str =~ /^([ &:#-\@\w.]+)$/) {
        $str = $1; #data is now untainted
    } else {
        $str = "";
    }
    return($str);
}

