Diff for /loncom/CrGenerate.pl between versions 1.4 and 1.9

version 1.4, 2004/06/30 11:14:35 version 1.9, 2009/02/02 13:27:45
Line 48 Line 48
 # Import section:  # Import section:
   
 use strict;  use strict;
   use lib '/home/httpd/lib/perl';
 use MIME::Entity;  use MIME::Entity;
 use Mail::Mailer;  
 use LONCAPA::Configuration;  use LONCAPA::Configuration;
 use File::Copy;  use File::Copy;
   
Line 71  my $WebGroup="www";  # Group name runnin Line 71  my $WebGroup="www";  # Group name runnin
   
 #   Debug/log support:  #   Debug/log support:
 #  #
 my $DEBUG = 1; # 1 for on, 0 for off.  my $DEBUG = 0; # 1 for on, 0 for off.
   
 # Send debugging to stderr.  # Send debugging to stderr.
 # Parameters:  # Parameters:
Line 80  my $DEBUG = 1;   # 1 for on, 0 for off. Line 80  my $DEBUG = 1;   # 1 for on, 0 for off.
 #    $DEBUG - message is only written if this is true.  #    $DEBUG - message is only written if this is true.
 #  #
 sub Debug {  sub Debug {
     my $msg  = shift;      my ($msg)  = @_;
     if($DEBUG) {      if($DEBUG) {
  print STDERR "$msg\n";   print STDERR "$msg\n";
     }      }
 }  }
   
 #  #
   #  Decodes the email address from a textual certificate request
   #  file:
   # Parameters:
   #    $RequestFile   - Name of the file containing the textual
   #                     version of the certificate request.
   # Returns:
   #   Email address contained in the request.
   # Failure:
   #   If unable to open or unable to fine an email address in the file,
   #   dies with a message.
   #
   sub DecodeEmailFromRequest {
       Debug("DecodeEmailFromRequest");
   
       my ($RequestFile) = @_;
       Debug("Request file is called $RequestFile");
   
       # We need to look for the line that has a "/Email=" in it.
   
       Debug("opening $RequestFile");
       open REQUEST, "< $RequestFile" or
    die "Unable to open $RequestFile to parse return e-mail address";
   
       Debug("Parsing request file");
       my $line;
       my $found = 0;
       while($line = <REQUEST>) {
    chomp($line); # Never a bad idea.
    if($line =~ /\/Email=/) {
       $found = 1;
       last;
    }
       }
       if(!$found) {
    die "There does not appear to be an e-mail address in $RequestFile";
       }
   
       close REQUEST;
   
       Debug("Found /Email in $line");
       
       # $line contains a bunch of comma separated key=value pairs.
       # The problem is that after these is a /Email=<what-we-want>
       # first we'll split the line up at the commas.
       # Then we'll look for the entity with the /Email in it.
       # That line will get split at the / and then the Email=<what-we-want>
       # gets split at the =.  I'm sure there's some clever regular expression
       # substitution that will get it all in a single line, but I think 
       # this approach is gonna be much easier to understand than punctuation
       # sneezed all over the page:
      
       my @commalist = split(/,/, $line);
       my $item;
       my $emailequals = "";
       foreach $item  (@commalist) {
    if($item =~ /\/Email=/) { # gotcha...
       $emailequals = $item;
       last;
    }
       }
   
       Debug("Pulled out $emailequals from $line");
       my ($trash, $addressequals) = split(/\//, $emailequals);
       Debug("Futher pulled out $addressequals");
   
       my ($junk, $address) = split(/=/, $addressequals);
       Debug("Parsed final e-mail address as $address");
       
   
   
       return $address;
   }
   
   #
 #   Read the LonCAPA web config files to get the values of the   #   Read the LonCAPA web config files to get the values of the 
 #   configuration global variables we need:  #   configuration global variables we need:
 # Implicit inputs:  # Implicit inputs:
Line 186  sub GenerateRequest { Line 260  sub GenerateRequest {
     print "information.  Most of this information is for documentation\n";      print "information.  Most of this information is for documentation\n";
     print "purposes only, so it's not critical if you make a mistake.\n";      print "purposes only, so it's not critical if you make a mistake.\n";
     print "However:  The generated certificate will be sent to the \n";      print "However:  The generated certificate will be sent to the \n";
     print "Email address you provide, and you should leave the optional\n";      print "E-mail address you provide, and you should leave the optional\n";
     print "Challenge password blank.\n";      print "Challenge password blank.\n";
   
     my $requestcmd = $SSLCommand." req -newkey rsa:1024 "      my $requestcmd = $SSLCommand." req -newkey rsa:1024 "
Line 206  sub GenerateRequest { Line 280  sub GenerateRequest {
     my $decodecmd = $SSLCommand." rsa -in  hostkey.pem"      my $decodecmd = $SSLCommand." rsa -in  hostkey.pem"
                                ."     -out hostkey.dec"                                 ."     -out hostkey.dec"
                                ."     -passin pass:$Passphrase";                                 ."     -passin pass:$Passphrase";
     my $status = system($decodecmd);      $status = system($decodecmd);
     if($status) {      if($status) {
  die "Host key decode failed";   die "Host key decode failed";
     }      }
   
     chmod(0600, "hostkey.dec"); # Protect the decoded hostkey.      chmod(0600, "hostkey.dec"); # Protect the decoded hostkey.
   
       #  Create the textual version of the request too:
   
       Debug("Creating textual version of the request for users.");
       my $textcmd = $SSLCommand." req -in request.pem -text "
                        ." -out request.txt";
       $status = system($textcmd);
       if($status) {
    die "Textualization of the certificate request failed";
       }
                        
   
     Debug("Done");      Debug("Done");
 }  }
 #  #
Line 257  sub InstallKey { Line 343  sub InstallKey {
   
     Debug("Done");      Debug("Done");
 }  }
 sub MailRequest {}  #
 sub Cleanup {}  #  Package up a certificate request and email it to the loncapa
   #  admin.  The email sent:
   #   - Has the subject: "LonCAPA certificate request for hostname
   #   - Has, as the body, the text version of the certificate.
   #     This can be inspected by the human issuing the certificate
   #     to decide if they want to really grant it... it will
   #     have the return email and all the documentation fields.
   #   - Has a text attachment that consists of the .pem version of the
   #     request.  This is extracted by the human granting the 
   #     certificate and used as input to the CrGrant.pl script.
   #
   #
   # Implicit inputs:
   #    request.pem    - The certificate request file.
   #    request.txt    - Textual version of the request file.
   #    $RequestEmail  - Email address to which the key is sent.
   #  
   sub MailRequest {
       Debug("Mailing request");
   
       # First we need to pull out the return address from the textual
       # form of the certificate request:
   
       my $FromEmail = DecodeEmailFromRequest("request.txt");
       if(!$FromEmail) {
    die "From e-mail address cannot be decoded from certificate request";
       }
       Debug("Certificate will be sent back to $FromEmail");
   
       # Create the email message headers and all:
       #
       Debug("Creating top...level...");
       my $top = MIME::Entity->build(Type     => "multipart/mixed",
     From     => $FromEmail,
     To       => $RequestEmail,
     Subject  => "LonCAPA certificate request");
       if(!$top) {
    die "Unable to create top level mime document";
       }
       Debug("Attaching Text formatted certificate request");
       $top->attach(Path     => "request.txt");
   
   
       Debug("Attaching PEM formatted certificate request...");
       $top->attach(Type       => "text/plain",
    Path      => "request.pem");
   
       #  Now send the email via sendmail this should work as long as
       #  sendmail or postfix are configured properly.  Most other mailers
       #  define the sendmail command too for compatibility with what
       #  we're trying to do.  I decided to use sendmail directly because
       #  otherwise I'm not sure the mail headers I created in $top
       #  will get properly passed as headers to other mailer thingies.
       #
   
       Debug("Mailing..");
   
       open MAILPIPE, "| /usr/lib/sendmail -t -oi -oem" or 
    die "Failed to open pipe to sendmail: $!";
       $top->print(\*MAILPIPE);
       close MAILPIPE;
   
   
   
       Debug("Done");
   } 
   
   #
   #   Cleans up the detritus that's been created by this 
   #   script (see Implicit inputs below).
   # Implicit inputs:
   #    request.pem       - Name of certificate request file in PEM format
   #                        which will be deleted.
   #    request.txt       - Name of textual equivalent of request file
   #                        which will also be deleted.
   #    hostkey.pem       - Encrypted host key which will be deleted.
   #    hostkey.dec       - Decoded host key, which will be deleted.
   #
   sub Cleanup {
       Debug("Cleaning up generated, temporary files");
       unlink("request.pem", "request.txt", "hostkey.pem", "hostkey.dec");
       Debug("done!");
   }
   
   
   
Line 272  MailRequest;   # Mail certificate reques Line 440  MailRequest;   # Mail certificate reques
 Cleanup; # Cleanup temp files created.  Cleanup; # Cleanup temp files created.
   
 Debug("Done");  Debug("Done");
   
   #---------------------- POD documentatio --------------------
   
   =head1 NAME
    
       CrGenerate - Generate a loncapa certificate request.
   
   =head1 SYNOPSIS
   
   Usage: B<CrGenerate>
   
   This should probably be run automatically at system
   installation time.  Root must run this as write access is 
   required to /home/httpd.
   
   This is a command line script that:
   
      - Generates a hostkey and certificate request.
      - Installs the protected/decoded host key where
        secure lond/lonc can find it.
      - Emails the certificate request to the loncapa certificate
        manager.
   
   In due course if all is legitimate, the loncapa certificate
   manager will email a certificate installation script to 
   the local loncapa system administrator.
   
   =head1 DESCRIPTION
   
   Using the default openssl configuration file, a certificate
   request and local hostkey are created in the current working
   directory.  The local host key is decoded and installed in the 
   loncapa certificate directory.  This allows the secure versions 
   of lonc and lond to locate them when attempting to form 
   external connections.  The key file is given mode
   0400 to secure it from prying eyes.
   
   The certificate request in PEM form is attached to an email that
   contains the textual equivalent of the certificate request 
   and sent to the loncapa certificate manager.  All temporary
   files (certificate request, keys etc.) are removed from the
   current working directory.
   
   It is recommended that the directory this script is run in have 
   permission mask 0700 to ensure that there are no timing holes
   during which the decoded host key file can be stolen.
   
   During certificate generation, the user will receive several 
   prompts.  For the default LonCAPA  openssl configuration, 
   these prompts, and documentation and sample responses
   in angle brackets (<>)  are shown below:
   
       Country Name (2 letter code) [GB]: <your country e.g. US>
       State or Province Name (full name) [Berkshire]: <State, province prefecture etc. e.g. Michigan>
       Locality Name (eg, city) [Newbury]: <City township or  municipality e.g. East Lansing>
       Organization Name (eg, company) [My Company Ltd]: <corporate entity e.g. Michigan State University>
       Organizational Unit Name (eg, section) []: <unit within Organization e.g. LITE lab>
       Common Name (eg, your name or your server's host name) [] <server's hostname e.g. myhost.university.edu>
       Email Address []: <Address to which the granted certificate should be sent e.g. me@university.edu>
       
       Please enter the following 'extra' attributes
       to be sent with your certificate request
       A challenge password []: <leave this blank!!!!!>
       An optional company name []: <Put whatever you want or leave blank>
   
   
   =head1  DEPENDENCIES
   
    - MIME::Entity           Used to create the email message.
    - LONCAPA::Configuration Used to parse the loncapa configuration files.
    - File::Copy             Used to install the key file.
    - /usr/lib/sendmail      Properly configured sendmail, used to send the
                             certificate request email to the loncapa
                             certificate administrator.
    - /etc/httpd/conf/*      Loncapa configuration files read to locate
                             the certificate directory etc.
   
   =head1 FILES
   
     The following temporary files are created in the cwd
   
     hostkey.pem         - PEM formatted version of the encrypted host key.
     hostkey.dec         - PEM formatted decrypted version of the host key.
     request.pem         - PEM formatted certificate request.
     request.txt         - Textual rendering of the certificate request.
   
     The following permanent file is created:
   
     $CertDir/$Keyfile   - The installed decoded host key file. $CertDir
                           is defined by the Perl variable lonCertificateDirectory
                           in /etc/loncapa_apache.conf while $Keyfile is 
                           defined by the perl variable lonnetPrivateKey in the
                           same configuration file.
     
   =head1 COPYRIGHT:
   
    Copyright Michigan State University Board of Trustees
   
    This file is part of the LearningOnline Network with CAPA (LON-CAPA).
   
    LON-CAPA 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 2 of the License, or 
    (at your option) any later version.
   
    LON-CAPA 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 LON-CAPA; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   
    /home/httpd/html/adm/gpl.txt
   
   
   =cut
   
   
       

Removed from v.1.4  
changed lines
  Added in v.1.9


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>