[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.