[LON-CAPA-cvs] cvs: loncom / CrGenerate.pl

foxr lon-capa-cvs@mail.lon-capa.org
Wed, 30 Jun 2004 11:14:36 -0000


foxr		Wed Jun 30 07:14:36 2004 EDT

  Modified files:              
    /loncom	CrGenerate.pl 
  Log:
  Implement:
  GenerateRequest - Generate the hostkey and the certificate request for  
                    the host.  
  InstallKey      - Install the host key, if necessary creating the
                    target directory.
  
  Note that keys are locked down tight, even the encoded key.  This is because:
  - The encoded key's passphrase is 'well known'.
  - The decoded key can be used to forge signatures certificates etc. and that would be 
    bad.
  
  
  
Index: loncom/CrGenerate.pl
diff -u loncom/CrGenerate.pl:1.3 loncom/CrGenerate.pl:1.4
--- loncom/CrGenerate.pl:1.3	Tue Jun 29 07:32:06 2004
+++ loncom/CrGenerate.pl	Wed Jun 30 07:14:35 2004
@@ -2,7 +2,7 @@
 # The LearningOnline Network
 # CrGenerate - Generate a loncapa certificate request.
 #
-# $Id: CrGenerate.pl,v 1.3 2004/06/29 11:32:06 foxr Exp $
+# $Id: CrGenerate.pl,v 1.4 2004/06/30 11:14:35 foxr Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -51,16 +51,23 @@
 use MIME::Entity;
 use Mail::Mailer;
 use LONCAPA::Configuration;
+use File::Copy;
 
-#  Global variable declarations:
+#  Global variable declarations:4
 
 my $SSLCommand;			  # Full path to openssl command.
 my $CertificateDirectory;	  # LONCAPA Certificate directory.
 my $KeyFilename;	          # Key filename (within CertificateDirectory).
-my $Passphrase="loncapawhatever"; # Initial passphrase for keyfile
 my $RequestEmail;		  # Email address of loncapa cert admin.
+my $WebUID;			# UID of web user.
+my $WebGID;			# GID of web user.
 
+my $Passphrase="loncapawhatever";      # Initial passphrase for keyfile
+my $RequestFile="loncapaRequest.pem";  # Name of Certificate request file.
+my $EncodedKey="hostkey.pem";	       # Name of encoded key file.
 
+my $WebUser="www";		# Username running the web server.
+my $WebGroup="www";		# Group name running the web server.
 
 #   Debug/log support:
 #
@@ -134,9 +141,122 @@
     else {
 	die "Could not read SSLEmail coniguration key";
     }
+    #  The UID/GID of the web user: It's possible the web user's
+    #  GID is not its primary, so we'll translate that form the
+    #  group file separately.
+
+    my ($login, $pass, $uid, $gid) = getpwnam($WebUser);
+    if($uid) {
+	$WebUID = $uid;
+	Debug("Web user: $WebUser -> UID: $WebUID");
+    }
+    else {
+	die "Could not translate web user: $WebUser to a uid.";
+    }
+    my $gid = getgrnam($WebGroup);
+    if($gid) {
+	$WebGID = $gid;
+	Debug("Web group: $WebGroup -> GID $WebGID");
+    }
+    else {
+	die "Unable to translate web group $WebGroup to a gid.";
+    }
+}
+#
+#   Generate a certificate request.
+#   The openssl command is issued to create a local host key and
+#   a certificate request.  The key is initially encoded.
+#   We will eventually decode this, however, since the key
+#   passphrase is open source we'll protect even the initial 
+#   encoded key file too.  We'll need to decode the keyfile since
+#   otherwise, openssl will need a passphrase everytime an ssl connection
+#   is created (ouch).
+# Implicit Inputs:
+#    Passphrase   - Initial passphrase for the encoded key.
+#    RequestFile  - Filename of the certificate request.
+#    EncodedKey   - Filename of the encoded key file.
+#
+# Side-Effects:
+#
+sub GenerateRequest {
+    Debug("Generating the request and key");
+
+    print "We are now going to generate the certificate request\n";
+    print "You will be prompted by openssl for several pieces of \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 "However:  The generated certificate will be sent to the \n";
+    print "Email address you provide, and you should leave the optional\n";
+    print "Challenge password blank.\n";
+
+    my $requestcmd = $SSLCommand." req -newkey rsa:1024 "
+                                ." -keyout hostkey.pem "
+                                ." -keyform PEM "
+                                ." -out request.pem "
+                                ." -outform PEM "
+                                ." -passout pass:$Passphrase";
+    my $status = system($requestcmd);
+    if($status) {
+	die "Certificate request generation failed: $status";
+    }
+
+    chmod(0600, "hostkey.pem");	# Protect key since passphrase is opensrc.
+
+    Debug("Decoding the key");
+    my $decodecmd = $SSLCommand." rsa -in  hostkey.pem"
+                               ."     -out hostkey.dec"
+                               ."     -passin pass:$Passphrase";
+    my $status = system($decodecmd);
+    if($status) {
+	die "Host key decode failed";
+    }
+
+    chmod(0600, "hostkey.dec");	# Protect the decoded hostkey.
+    Debug("Done");
+}
+#
+#  Installs the decoded host key (hostkey.dec) in the 
+#  certificate directory with the correct permissions.
+#
+# Implicit Inputs:
+#    hostkey.dec           - the name of the host key file.
+#    $CertificateDirectory - where the key file gets installed
+#    $KeyFilename          - Final name of the key file.
+#    $WebUser              - User who should own the key file.
+#    $WebGroup             - Group who should own the key file.
+#    0400                  - Permissions to give to the installed key
+#                            file.
+#    0700                  - Permissions given to the certificate
+#                            directory if created.
+# Side-Effects:
+#    If necessary, $CertificateDirectory is created.
+#    $CertificateDirectory/$KeyFilename is ovewritten with the
+#          contents of hostkey.dec in the cwd.
+#
+sub InstallKey {
+    Debug("InstallKey");
+
+    Debug("Need to create certificate directory?");
+    if(!(-d $CertificateDirectory)) {
+	
+	Debug("Creating");
+	mkdir($CertificateDirectory, 0700);
+	chown($WebUID, $WebGID, $CertificateDirectory);
+    }
+    else {
+	Debug("Exists");
+    }
+
+    Debug("Installing the key file:");
+    my $FullKeyPath = $CertificateDirectory."/".$KeyFilename;
+    copy("hostkey.dec", $FullKeyPath);
+
+    Debug("Setting ownership and permissions");
+    chmod(0400, $FullKeyPath);
+    chown($WebUID, $WebGID, $FullKeyPath);
+
+    Debug("Done");
 }
-sub GenerateRequest {}
-sub InstallKey {}
 sub MailRequest {}
 sub Cleanup {}