[LON-CAPA-cvs] cvs: loncom / CrGrant.pl
foxr
lon-capa-cvs@mail.lon-capa.org
Mon, 05 Jul 2004 11:37:40 -0000
foxr Mon Jul 5 07:37:40 2004 EDT
Modified files:
/loncom CrGrant.pl
Log:
Implemenet the actual certificate generation and parsing of the
certificate file to get the email address to receive the granted
certificates.
Index: loncom/CrGrant.pl
diff -u loncom/CrGrant.pl:1.1 loncom/CrGrant.pl:1.2
--- loncom/CrGrant.pl:1.1 Fri Jul 2 06:51:18 2004
+++ loncom/CrGrant.pl Mon Jul 5 07:37:39 2004
@@ -2,7 +2,7 @@
# The LearningOnline Network
# CrGrant.pl - Grant a loncapa SSL certificate.
#
-# $Id: CrGrant.pl,v 1.1 2004/07/02 10:51:18 foxr Exp $
+# $Id: CrGrant.pl,v 1.2 2004/07/05 11:37:39 foxr Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -55,14 +55,8 @@
# o The certificate authority files are in $SSLDir/loncapaca
# o The certificate authority certificate is in:
# $SSLDir/loncapaca/cacert.pem
-# o The certificate authority maintains a certificate index file
-# $SSLDIR/loncapaca/index.txt
-# o Only one instance of this script will be run at a time!!!!!
-# (otherwise the last line of the index file may not be the
-# index to our certificate. We'll do some rudimentary
-# error checking, but have no idea how to recover in case
-# of problems).
-# o The generated certificates are stored in $SSLDIR/loncapaca/certs
+# o Only one instance of this script will be run at a time in
+# this directory.
# o The person that runs this script knows the passphrase
# for the loncapa certificate authority's private key
# which remains encrypted for security reasons.
@@ -80,7 +74,12 @@
# Global variable declarations
+my $ssl_command = "/usr/bin/openssl "; # Command to run openssl.
+my $ssl_dir = "/usr/share/ssl"; # Where ssl config files etc. live
+my $ca_cert_file = $ssl_dir."/loncapa/cacert.pem"; # CA's certificate file.
+my $ca_config_file= $ssl_dir."/loncapaca.cnf"; # CA's config file.
+
# Debug/log support
@@ -94,12 +93,126 @@
}
# Support subs:
-sub Usage {}
+#
+# Print out program usage.
+#
+# Side effects:
+# Output goes to stderr.
+#
+sub Usage {
+ print STDERR << "USAGE";
+
+Usage:
+ CrGrant.pl requestfile.pem
+Where:
+ requestfile.pem is a PEM formatted certificate extracted from an email
+ to the LonCAPA certificate manager.
+USAGE
+
+}
+# Create a certificate from the request file. The certificate
+# is used, in conjunction with the openssl command with the
+# certificate authority configuration to produce a certificate
+# file.
+#
+# The certificate is parsed to determine the email address
+# of the requestor, which is returned to the caller.
+#
+#Parameters:
+# request_file - Name of the file containing the certificate request.
+#Returns:
+# If the request file exists and is able to produce a certificate
+# the email address of the requester is returned to the caller.
+# If not, undef is returned.
+#
sub CreateCertificate {
- my $RequestFile = shift;
+ my ($request_file) = @_;
+
+ Debug("CreateCertificate");
+
+ if(!(-e $request_file)) {
+ Debug("Certificate file $request_file does not exist");
+ return undef;
+ }
+ Debug("Certificate file $request_file exists");
+
+ # Create the certificate: The status of the openssl command
+ # is used to determine if the certificate succeeded:
+
+ my $create_command = $ssl_command." ca -config ".$ca_config_file
+ ." -in ".$request_file
+ ." -out hostCertificate.pem";
+ my $status = system($create_command);
+ if($status) {
+ Debug("openssl ca failed");
+ print STDERR "Certificate generation failed... probably bad";
+ print STDERR " request file!\n";
+ return undef;
+ }
+ Debug("openssl ca succeeded");
+
+ # Now we have a shining new signed certificate in ./hostCertificate.pem
+ # we parse it to get the email address to which the certificate should
+ # be emailed.
+ # The certificate's return email address will be in the Subject line:
+ #
+
+ Debug("Parsing certificate file for Subject:");
+ open CERTIFICATE, "<hostCertificate.pem";
+ my $line;
+ my $subject_found = 0;
+ while ($line = <CERTIFICATE>) {
+ Debug("Line = $line");
+ if($line =~ /Subject:/) {
+ Debug("Found Subject: in $line");
+ $subject_found =1;
+ last;
+ }
+ }
+ close CERTIFICATE;
+
+ if(!$subject_found) {
+ Debug("Did not find Subject line in cert");
+ print STDERR "Output certificate parse failed: no Subject:\n";
+ return undef;
+ }
+ # The subject line contains an Email= string amidst the other stuff.
+ # First break in to comma separated stuff, then locate the piece that
+ # contains /Email=
+
+ my @subject_fields = split(/,/, $line);
+ my $email_found = 0;
+ my $element;
+ my $email_element;
+ Debug("Parsing subject line for Email=");
+ foreach $element (@subject_fields) {
+ $email_element = $element;
+ Debug("Parsing $element");
+ if($element =~ /\/Email=/) {
+ Debug("Found /Email=");
+ $email_found = 1;
+ last;
+ }
+ }
+ if(!$email_found) {
+ Debug("Failed to fine Email=");
+ print STDERR "Unable to find line with /Email= in cert. Subject\n";
+ return undef;
+ }
+
+ # The piece we found must first be split at the /
+ # to isolate the Email= part and then that part at the = to isolate
+ # the address:
+
+ Debug("Splitting $email_element at /");
+ my ($junk, $email) = split(/\//, $email_element);
+ Debug("Email part is $email");
+ my ($junk, $address) = split(/=/, $email);
+ Debug("CreateCertificate Returning $address to caller");
+
+ return $address;
- return 'fox@nscl.msu.edu'; # Stub..
}
sub CreateInstallScript {}
@@ -125,10 +238,17 @@
}
my $CertificateRequest = $ARGV[0];
-my $EmailAddress = CreateCertificate($CertificateRequest);
+my $email_address = CreateCertificate($CertificateRequest);
+
+if(!defined $email_address) {
+ print STDERR "Bad or missing certificate file!!";
+ Usage;
+ exit -1;
+}
+
CreateInstallScript;
my $Message = CreateEmail;
-SendEmail($EmailAddress, $Message);
+SendEmail($email_address, $Message);
Cleanup;
# POD documentation.