Add ability for xCAT to sign client certificates

git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@10414 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
jbjohnso 2011-08-31 13:33:38 +00:00
parent 47db3e0642
commit 6ad28fa9ae

View File

@ -181,6 +181,59 @@ sub process_request
push @{$rsp->{'data'}},{content=>[$tabdata],desc=>[$_]};
unlink "/tmp/xcat/keytab.$$";
next;
} elsif (/x509cert/) {
my $csr = $request->{'csr'}->[0];
my $csrfile;
my $oldumask = umask 0077;
if (-e "/tmp/xcat/client.csr.$$") { unlink "/tmp/xcat/client.csr.$$"; }
open($csrfile,">","/tmp/xcat/client.csr.$$");
unless($csrfile) { next; }
my @statdat = stat $csrfile;
while ($statdat[4] != 0 or $statdat[2] & 020 or $statdat[2] & 002) { #try to be paranoid, root better own the file, and it better not be writable by anyone but owner
#this means to assure the filehandle is not write-accessible to others who may insert their malicious CSR
close($csrfile);
unlink("/tmp/xcat/client.csr.$$");
open($csrfile,">","/tmp/xcat/client.csr.$$");
@statdat = stat $csrfile;
}
print $csrfile $csr;
close($csrfile);
#ok, at this point, we can verify that the subject is one we wouldn't mind signing...
my $subject=`openssl req -in /tmp/xcat/client.csr.$$ -subject -noout`;
chomp($subject);
unless ($subject =~ /CN=$client\z/) { unlink("/tmp/xcat/client.csr.$$"); next; }
unlink "/tmp/xcat/client.cert.$$";
open($csrfile,">","/tmp/xcat/client.cert.$$");
@statdat = stat $csrfile;
while ($statdat[4] != 0 or $statdat[2] & 020 or $statdat[2] & 002) { #try to be paranoid, root better own the file, and it better not be writable by anyone but owner
#this prevents an attacker from predicting pid and pre-setting up a file that they can corrupt for DoS
close($csrfile);
unlink("/tmp/xcat/client.csr.$$");
open($csrfile,">","/tmp/xcat/client.csr.$$");
@statdat = stat $csrfile;
}
close($csrfile);
open($csrfile,"<","/etc/xcat/ca/index");
my @caindex = <$csrfile>;
close($csrfile);
foreach (@caindex) {
chomp;
my ($type, $expiry, $revoke, $serial, $fname, $subject) = split /\t/;
if ($type eq 'V' and $subject =~ /CN=$client\z/) { #we already have a valid certificate, new request replaces it, revoke old
print "The time of replacing is at hand for $client\n";
system("openssl ca -config /etc/xcat/ca/openssl.cnf -revoke /etc/xcat/ca/certs/$serial.pem");
}
}
my $rc = system("openssl ca -config /etc/xcat/ca/openssl.cnf -in /tmp/xcat/client.csr.$$ -out /tmp/xcat/client.cert.$$ -batch");
unlink("/tmp/xcat/client.csr.$$");
umask ($oldumask);
if ($rc) { next; }
open ($csrfile,"<","/tmp/xcat/client.cert.$$");
my @certdata = <$csrfile>;
close($csrfile);
unlink "/tmp/xcat/client.cert.$$";
my $certcontents = join('',@certdata);
push @{$rsp->{'data'}},{content=>[$certcontents],desc=>[$_]};
} else {
next;
}