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>