Annotation of loncom/CrGenerate.pl, revision 1.4

1.1       foxr        1: #!/usr/bin/perl
                      2: # The LearningOnline Network
                      3: # CrGenerate - Generate a loncapa certificate request.
                      4: #
                      5: # $Id$
                      6: #
                      7: # Copyright Michigan State University Board of Trustees
                      8: #
                      9: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                     10: #
                     11: # LON-CAPA is free software; you can redistribute it and/or modify
                     12: # it under the terms of the GNU General Public License as published by
                     13: # the Free Software Foundation; either version 2 of the License, or 
                     14: # (at your option) any later version.
                     15: #
                     16: # LON-CAPA is distributed in the hope that it will be useful,
                     17: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     18: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     19: # GNU General Public License for more details.
                     20: #
                     21: # You should have received a copy of the GNU General Public License
                     22: # along with LON-CAPA; if not, write to the Free Software
                     23: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     24: #
                     25: # /home/httpd/html/adm/gpl.txt
                     26: #
                     27: 
                     28: 
                     29: # http://www.lon-capa.org/
                     30: #
                     31: #
                     32: #  This script:
                     33: #  1. Generates a private host key and certificate request/
                     34: #  2. Decodes the private host key
                     35: #  3. Installs the private host key with appropriate permissions
                     36: #     in the  appropriate directory (sorry to be vague about this, but
                     37: #     the installation directory is determined by external configuration
                     38: #     info).
                     39: # 4. Constructs an email to the loncapa cluster administrator
                     40: #    consisting of a generic heading and the certificate request as a MIME
                     41: #    attachment.
                     42: # 5. Sends the email and
                     43: # 6. Cleans up after itself by removing any temp files generated.
                     44: #
                     45: #
                     46: 
                     47: 
                     48: # Import section:
                     49: 
                     50: use strict;
                     51: use MIME::Entity;
                     52: use Mail::Mailer;
                     53: use LONCAPA::Configuration;
1.4     ! foxr       54: use File::Copy;
1.1       foxr       55: 
1.4     ! foxr       56: #  Global variable declarations:4
1.1       foxr       57: 
1.2       foxr       58: my $SSLCommand;			  # Full path to openssl command.
                     59: my $CertificateDirectory;	  # LONCAPA Certificate directory.
                     60: my $KeyFilename;	          # Key filename (within CertificateDirectory).
                     61: my $RequestEmail;		  # Email address of loncapa cert admin.
1.4     ! foxr       62: my $WebUID;			# UID of web user.
        !            63: my $WebGID;			# GID of web user.
1.1       foxr       64: 
1.4     ! foxr       65: my $Passphrase="loncapawhatever";      # Initial passphrase for keyfile
        !            66: my $RequestFile="loncapaRequest.pem";  # Name of Certificate request file.
        !            67: my $EncodedKey="hostkey.pem";	       # Name of encoded key file.
1.3       foxr       68: 
1.4     ! foxr       69: my $WebUser="www";		# Username running the web server.
        !            70: my $WebGroup="www";		# Group name running the web server.
1.3       foxr       71: 
1.1       foxr       72: #   Debug/log support:
                     73: #
1.2       foxr       74: my $DEBUG = 1;			# 1 for on, 0 for off.
1.1       foxr       75: 
                     76: # Send debugging to stderr.
                     77: # Parameters:
                     78: #     msg   - Message to send to stderr.
                     79: # Implicit Inputs:
                     80: #    $DEBUG - message is only written if this is true.
                     81: #
                     82: sub Debug {
1.2       foxr       83:     my $msg  = shift;
1.1       foxr       84:     if($DEBUG) {
                     85: 	print STDERR "$msg\n";
                     86:     }
                     87: }
                     88: 
1.3       foxr       89: #
                     90: #   Read the LonCAPA web config files to get the values of the 
                     91: #   configuration global variables we need:
                     92: # Implicit inputs:
                     93: #   loncapa.conf   - configuration file to read (user specific).
                     94: # Implicit outputs (see global variables section):
                     95: #   SSLCommand,
                     96: #   CertificateDirectory
                     97: #   KeyfileName
                     98: #   RequestEmail
                     99: # Side-Effects:
                    100: #   Exit with error if cannot complete.
                    101: #
                    102: sub ReadConfig {
                    103: 
                    104:     Debug("Reading configuration");
                    105:     my $perlvarref = LONCAPA::Configuration::read_conf('loncapa.conf');
                    106:     
                    107:     # Name of the SSL Program
                    108: 
                    109:     if($perlvarref->{SSLProgram}) {
                    110: 	$SSLCommand = $perlvarref->{SSLProgram};
                    111: 	Debug("SSL Command: $SSLCommand");
                    112:     }
                    113:     else {
                    114: 	die "Unable to read the SSLCommand configuration option\n";
                    115:     }
                    116: 
                    117:     # Where the certificates, and host key are installed:
1.1       foxr      118: 
1.3       foxr      119:     if($perlvarref->{lonCertificateDirectory}) {
                    120: 	$CertificateDirectory = $perlvarref->{lonCertificateDirectory};
                    121: 	Debug("Local certificate Directory: $CertificateDirectory");
                    122:     }
                    123:     else {
                    124: 	die "Unable to read SSLDirectory configuration option\n";
                    125:     }
                    126:     # The name of the host key file (to be installed in SSLDirectory).
                    127:     #
                    128:     if($perlvarref->{lonnetPrivateKey}) {
                    129: 	$KeyFilename  = $perlvarref->{lonnetPrivateKey};
                    130: 	Debug("Private key will be installed as $KeyFilename");
                    131:     } 
                    132:     else {
                    133: 	die "Unable to read lonnetPrivateKey conrig paraemter\n";
                    134:     }
                    135:     #  The email address to which the certificate request is sent:
                    136: 
                    137:     if($perlvarref->{SSLEmail}) {
                    138: 	$RequestEmail = $perlvarref->{SSLEmail};
                    139: 	Debug("Certificate request will be sent to $RequestEmail");
                    140:     }
                    141:     else {
                    142: 	die "Could not read SSLEmail coniguration key";
                    143:     }
1.4     ! foxr      144:     #  The UID/GID of the web user: It's possible the web user's
        !           145:     #  GID is not its primary, so we'll translate that form the
        !           146:     #  group file separately.
        !           147: 
        !           148:     my ($login, $pass, $uid, $gid) = getpwnam($WebUser);
        !           149:     if($uid) {
        !           150: 	$WebUID = $uid;
        !           151: 	Debug("Web user: $WebUser -> UID: $WebUID");
        !           152:     }
        !           153:     else {
        !           154: 	die "Could not translate web user: $WebUser to a uid.";
        !           155:     }
        !           156:     my $gid = getgrnam($WebGroup);
        !           157:     if($gid) {
        !           158: 	$WebGID = $gid;
        !           159: 	Debug("Web group: $WebGroup -> GID $WebGID");
        !           160:     }
        !           161:     else {
        !           162: 	die "Unable to translate web group $WebGroup to a gid.";
        !           163:     }
        !           164: }
        !           165: #
        !           166: #   Generate a certificate request.
        !           167: #   The openssl command is issued to create a local host key and
        !           168: #   a certificate request.  The key is initially encoded.
        !           169: #   We will eventually decode this, however, since the key
        !           170: #   passphrase is open source we'll protect even the initial 
        !           171: #   encoded key file too.  We'll need to decode the keyfile since
        !           172: #   otherwise, openssl will need a passphrase everytime an ssl connection
        !           173: #   is created (ouch).
        !           174: # Implicit Inputs:
        !           175: #    Passphrase   - Initial passphrase for the encoded key.
        !           176: #    RequestFile  - Filename of the certificate request.
        !           177: #    EncodedKey   - Filename of the encoded key file.
        !           178: #
        !           179: # Side-Effects:
        !           180: #
        !           181: sub GenerateRequest {
        !           182:     Debug("Generating the request and key");
        !           183: 
        !           184:     print "We are now going to generate the certificate request\n";
        !           185:     print "You will be prompted by openssl for several pieces of \n";
        !           186:     print "information.  Most of this information is for documentation\n";
        !           187:     print "purposes only, so it's not critical if you make a mistake.\n";
        !           188:     print "However:  The generated certificate will be sent to the \n";
        !           189:     print "Email address you provide, and you should leave the optional\n";
        !           190:     print "Challenge password blank.\n";
        !           191: 
        !           192:     my $requestcmd = $SSLCommand." req -newkey rsa:1024 "
        !           193:                                 ." -keyout hostkey.pem "
        !           194:                                 ." -keyform PEM "
        !           195:                                 ." -out request.pem "
        !           196:                                 ." -outform PEM "
        !           197:                                 ." -passout pass:$Passphrase";
        !           198:     my $status = system($requestcmd);
        !           199:     if($status) {
        !           200: 	die "Certificate request generation failed: $status";
        !           201:     }
        !           202: 
        !           203:     chmod(0600, "hostkey.pem");	# Protect key since passphrase is opensrc.
        !           204: 
        !           205:     Debug("Decoding the key");
        !           206:     my $decodecmd = $SSLCommand." rsa -in  hostkey.pem"
        !           207:                                ."     -out hostkey.dec"
        !           208:                                ."     -passin pass:$Passphrase";
        !           209:     my $status = system($decodecmd);
        !           210:     if($status) {
        !           211: 	die "Host key decode failed";
        !           212:     }
        !           213: 
        !           214:     chmod(0600, "hostkey.dec");	# Protect the decoded hostkey.
        !           215:     Debug("Done");
        !           216: }
        !           217: #
        !           218: #  Installs the decoded host key (hostkey.dec) in the 
        !           219: #  certificate directory with the correct permissions.
        !           220: #
        !           221: # Implicit Inputs:
        !           222: #    hostkey.dec           - the name of the host key file.
        !           223: #    $CertificateDirectory - where the key file gets installed
        !           224: #    $KeyFilename          - Final name of the key file.
        !           225: #    $WebUser              - User who should own the key file.
        !           226: #    $WebGroup             - Group who should own the key file.
        !           227: #    0400                  - Permissions to give to the installed key
        !           228: #                            file.
        !           229: #    0700                  - Permissions given to the certificate
        !           230: #                            directory if created.
        !           231: # Side-Effects:
        !           232: #    If necessary, $CertificateDirectory is created.
        !           233: #    $CertificateDirectory/$KeyFilename is ovewritten with the
        !           234: #          contents of hostkey.dec in the cwd.
        !           235: #
        !           236: sub InstallKey {
        !           237:     Debug("InstallKey");
        !           238: 
        !           239:     Debug("Need to create certificate directory?");
        !           240:     if(!(-d $CertificateDirectory)) {
        !           241: 	
        !           242: 	Debug("Creating");
        !           243: 	mkdir($CertificateDirectory, 0700);
        !           244: 	chown($WebUID, $WebGID, $CertificateDirectory);
        !           245:     }
        !           246:     else {
        !           247: 	Debug("Exists");
        !           248:     }
        !           249: 
        !           250:     Debug("Installing the key file:");
        !           251:     my $FullKeyPath = $CertificateDirectory."/".$KeyFilename;
        !           252:     copy("hostkey.dec", $FullKeyPath);
        !           253: 
        !           254:     Debug("Setting ownership and permissions");
        !           255:     chmod(0400, $FullKeyPath);
        !           256:     chown($WebUID, $WebGID, $FullKeyPath);
        !           257: 
        !           258:     Debug("Done");
1.3       foxr      259: }
1.1       foxr      260: sub MailRequest {}
                    261: sub Cleanup {}
                    262: 
                    263: 
                    264: 
                    265: #  Entry point:
                    266: 
                    267: Debug("Starting program");
                    268: ReadConfig;			# Read loncapa apache config file.
                    269: GenerateRequest;		# Generate certificate request.
                    270: InstallKey;			# Install the user's key.
                    271: MailRequest;			# Mail certificate request to loncapa 
                    272: Cleanup;			# Cleanup temp files created.
                    273: 
                    274: Debug("Done");

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