[LON-CAPA-cvs] cvs: doc /loncapafiles updatequery.piml

raeburn raeburn at source.lon-capa.org
Wed Aug 3 11:05:00 EDT 2016


raeburn		Wed Aug  3 15:05:00 2016 EDT

  Modified files:              
    /doc/loncapafiles	updatequery.piml 
  Log:
  - Prompt new installations to create certificate signing requests for
    LON-CAPA SSL certificates.
  - Determine if Admin E-mail, Support E-mail, and/or use of SSL by lonc and
    lond are retrieved from configuration.db on the domain's primary library
    server, instead of from loncapa.conf on each server.
  
  
-------------- next part --------------
Index: doc/loncapafiles/updatequery.piml
diff -u doc/loncapafiles/updatequery.piml:1.84 doc/loncapafiles/updatequery.piml:1.85
--- doc/loncapafiles/updatequery.piml:1.84	Sat Jul 30 00:38:14 2016
+++ doc/loncapafiles/updatequery.piml	Wed Aug  3 15:04:59 2016
@@ -1,6 +1,6 @@
 <!-- updatequery.piml -->
 
-<!-- $Id: updatequery.piml,v 1.84 2016/07/30 00:38:14 raeburn Exp $ -->
+<!-- $Id: updatequery.piml,v 1.85 2016/08/03 15:04:59 raeburn Exp $ -->
 
 <!--
 
@@ -34,6 +34,15 @@
 <perlscript mode='fg'>
 $|=1;
 use strict;
+use lib '/home/httpd/lib/perl/';
+use LONCAPA::Configuration;
+use LONCAPA::Lond;
+use LONCAPA::SSL;
+use LONCAPA;
+use GDBM_File;
+use Storable qw(thaw);
+use Term::ReadKey;
+use Locale::Country;
 
   print(<<END);
 
@@ -50,16 +59,192 @@
 
 END
 #sleep(3);
+
+sub get_static_config {
+# get LCperlvars from loncapa_apache.conf
+    my $confdir = '/etc/httpd/conf/';
+    if ('<DIST />' eq 'sles10' || '<DIST />' eq 'sles11' || '<DIST />' eq 'sles12' || '<DIST />' eq 'suse10.1' || '<DIST />' eq 'suse10.2' || '<DIST />' eq 'suse10.3' || '<DIST />' eq 'suse11.1' || '<DIST />' eq 'suse11.2' || '<DIST />' eq 'suse11.3' || '<DIST />' eq 'suse11.4' || '<DIST />' eq 'suse12.1' || '<DIST />' eq 'suse12.2' || '<DIST />' eq 'suse12.3' || '<DIST />' eq 'suse13.1' || '<DIST />' eq 'suse13.2' || '<DIST />' eq 'debian5' || '<DIST />' eq 'debian6' || '<DIST />' eq 'ubuntu6' || '<DIST />' eq 'ubuntu8' || '<DIST />' eq 'ubuntu10' || '<DIST />' eq 'ubuntu12' || '<DIST />' eq 'ubuntu14' || '<DIST />' eq 'ubuntu16') {
+        $confdir = '/etc/apache2/';
+    }
+    my $filename='loncapa_apache.conf';
+    my %LCperlvar;
+    if (-e "$confdir$filename") {
+        open(CONFIG,'<'.$confdir.$filename) or die("Can't read $confdir$filename");
+        while (my $configline=<CONFIG>) {
+            if ($configline =~ /^[^\#]?PerlSetVar/) {
+                my ($unused,$varname,$varvalue)=split(/\s+/,$configline);
+                chomp($varvalue);
+                $LCperlvar{$varname}=$varvalue;
+            }
+        }
+        close(CONFIG);
+    }
+    return \%LCperlvar;
+}
+
+sub get_domain_config {
+    my ($dom,$isprimary,$url,$perlvarref) = @_;
+    my %confhash;
+    if ($isprimary) {
+        if (ref($perlvarref) eq 'HASH') {
+            my $lonusersdir = $perlvarref->{'lonUsersDir'};
+            my $fname = $lonusersdir.'/'.$dom.'/configuration.db';
+            if (-e $fname) {
+                my $dbref=&LONCAPA::locking_hash_tie($fname,&GDBM_READER());
+                if (ref($dbref) eq 'HASH') {
+                    foreach my $key (sort(keys(%{$dbref}))) {
+                        my $value = $dbref->{$key};
+                        if ($value =~ s/^__FROZEN__//) {
+                            $value = thaw(&LONCAPA::unescape($value));
+                        } else {
+                            $value = &LONCAPA::unescape($value);
+                        }
+                        $confhash{$key} = $value;
+                    }
+                    &LONCAPA::locking_hash_untie($dbref);
+                }
+            }
+        }
+    } else {
+        if (open(PIPE,"wget --no-check-certificate '$url?domain=$dom&format=raw' |")) {
+            my $config = '';
+            while (<PIPE>) {
+                $config .= $_;
+            }
+            close(PIPE);
+            if ($config) {
+                my @pairs=split(/\&/,$config);
+                foreach my $item (@pairs) {
+                    my ($key,$value)=split(/=/,$item,2);
+                    my $what = &LONCAPA::unescape($key);
+                    if ($value =~ s/^__FROZEN__//) {
+                        $value = thaw(&LONCAPA::unescape($value));
+                    } else {
+                        $value = &LONCAPA::unescape($value); 
+                    }
+                    $confhash{$what}=$value;
+                }
+            }
+        }
+    }
+    return (\%confhash);
+}
+
+sub make_passphrase {
+    my ($got_passwd,$firstpass,$secondpass,$passwd);
+    my $maxtries = 10;
+    my $trial = 0;
+    while ((!$got_passwd) && ($trial < $maxtries)) {
+        $firstpass = &get_password('Enter password');
+        if (length($firstpass) < 6) {
+            print('Password too short.'."\n".
+              'Please choose a password with at least six characters.'."\n".
+              'Please try again.'."\n");
+        } elsif (length($firstpass) > 30) {
+            print('Password too long.'."\n".
+                  'Please choose a password with no more than thirty characters.'."\n".
+                  'Please try again.'."\n");
+        } else {
+            my $pbad=0;
+            foreach (split(//,$firstpass)) {if ((ord($_)<32)||(ord($_)>126)){$pbad=1;}}
+            if ($pbad) {
+                print('Password contains invalid characters.'."\n".
+                      'Password must consist of standard ASCII characters.'."\n".
+                      'Please try again.'."\n");
+            } else {
+                $secondpass = &get_password('Enter password a second time');
+                if ($firstpass eq $secondpass) {
+                    $got_passwd = 1;
+                    $passwd = $firstpass;
+                } else {
+                    print('Passwords did not match.'."\n".
+                          'Please try again.'."\n");
+                }
+            }
+        }
+        $trial ++;
+    }
+    return $passwd;
+}
+
+sub get_password {
+    my ($prompt) = @_;
+    local $| = 1;
+    print $prompt.': ';
+    my $newpasswd = '';
+    ReadMode 'raw';
+    my $key;
+    while(ord($key = ReadKey(0)) != 10) {
+        if(ord($key) == 127 || ord($key) == 8) {
+            chop($newpasswd);
+            print "\b \b";
+        } elsif(!ord($key) < 32) {
+            $newpasswd .= $key;
+            print '*';
+        }
+    }
+    ReadMode 'normal';
+    print "\n";
+    return $newpasswd;
+}
+
+sub send_mail {
+    my ($hostname,$recipient,$subj,$file) = @_;
+    my $from = 'www@'.$hostname;
+    my $certmail = "To: $recipient\n".
+                   "From: $from\n".
+                   "Subject: ".$subj."\n".
+                   "Content-type: text/plain\; charset=UTF-8\n".
+                   "MIME-Version: 1.0\n\n";
+    if (open(my $fh,"<$file")) {
+        while (<$fh>) {
+            $certmail .= $_;
+        }
+        close($fh);
+        $certmail .= "\n\n";
+        if (open(my $mailh, "|/usr/lib/sendmail -oi -t -odb")) {
+            print $mailh $certmail;
+            close($mailh);
+            print "Mail sent ($subj) to $recipient\n";
+        } else {
+            print "Sending mail ($subj) to $recipient failed.\n";
+        }
+    }
+    return;
+}
+
 </perlscript>
 </file>
 <file>
-<target dist='default'>loncom/hosts.tab</target>
+<target dist='default'>../../loncom/hosts.tab</target>
 <perlscript mode='fg'>
 my $lonCluster;
-unless (-l "<TARGET />") {
-  print(<<END);
+my $currCluster;
+
+if (-l "<TARGET />") {
+  my $currlink = readlink("<TARGET />");
+  if ($currlink =~ /^new_(existing|standalone|development|production)_hosts\.tab$/) {
+      $currCluster = $1;
+  }
+  my %clustertypes = (
+                       production  => 'PRODUCTION',
+                       standalone  => 'STAND-ALONE',
+                       development => 'DEVELOPMENT',
+                       existing    => 'RUNNING YOUR OWN CLUSTER',
+                     );
+  if (($currCluster) && (exists($clustertypes{$currCluster}))) {
+      print(<<END);
+
+The cluster type for this server is currently: $clustertypes{$currCluster}
+END
+
+  }
+}
+
+print(<<END);
 
 ===============================================================================
+
 Which cluster option would you like to have installed?
 IMPORTANT: to take advantage of the cluster options 1) and 3),
 you must contact loncapa\@loncapa.org.
@@ -117,7 +302,6 @@
     $lonCluster='rawhide'; $flag=1;
   }
 }
-}
 </perlscript>
 </file>
 <file>
@@ -130,6 +314,9 @@
 my $protocol;
 my $intdom;
 my $desiredhostname;
+my $city;
+my $state;
+my $country;
 my @libservers = ();
 unless (-e "<TARGET />") {
   print(<<END);
@@ -139,7 +326,7 @@
 or contact helpdesk\@loncapa.org.
 
 ===============================================================================
-The following 8 values are needed to configure LON-CAPA:
+The following 10 values are needed to configure LON-CAPA:
 * Machine Role
 * LON-CAPA Domain Name
 * LON-CAPA Machine ID Name
@@ -148,6 +335,8 @@
 * Web Server Protocol
 * Internet Domain Name of Your Institution
 * Hostname
+* City, State, Country for LON-CAPA SSL certificate 
+* Password for key for creating SSL certificates
 ===============================================================================
 
 In addition, a Support E-mail Address can also be included. If
@@ -434,7 +623,7 @@
 while (!$flag) {
   print(<<END);
 
-**** Server Administrators E-mail ****
+**** Server Administrator's E-mail ****
 E-mail address of the person who will manage this machine
 [should be in the form somebody\@somewhere]
 ENTER ADMIN E-MAIL ADDRESS:
@@ -566,7 +755,7 @@
 ****** Hostname of the server/VM *****
 
 The hostname of the server/VM is required. This will be similar to:
-somename.ustate.edu or somename.department.ustate.edu, and would be 
+somename.ustate.edu or somename.department.ustate.edu, and would be
 the web address which users would point their web browsers at to
 access the server.
 
@@ -598,6 +787,282 @@
   }
 }
 
+# get Country
+print(<<END);
+
+****** Information about Country, State or Province and City *****
+
+A two-letter country code, e.g., US, CA, DE etc. as defined by ISO 3166,
+is required. A state or province, and a city are also required.
+This locality information is included in two SSL certificates used internally
+by LON-CAPA, unless you are running standalone.
+
+If your server will be part of either the production or development 
+clusters, then the certificate will need to be signed by the official 
+LON-CAPA Certificate Authority (CA).  If you will be running your own 
+cluster then the cluster will need to create its own CA. 
+
+END
+
+my $posscountry;
+if ($desiredhostname =~ /\.(edu|com|org)$/) {
+    $posscountry = 'us';
+
+} else { 
+    ($posscountry) = ($desiredhostname =~ /\.(a-z){2}$/);
+}
+if ($posscountry) {
+    my $countrydesc = &Locale::Country::code2country($posscountry);
+    if ($countrydesc eq '') {
+        undef($posscountry);
+    }
+}
+
+$flag=0;
+while (!$flag) {
+  if ($posscountry) {
+     $posscountry = uc($posscountry);
+     print "ENTER TWO-LETTER COUNTRY CODE [$posscountry]:\n";
+  } else {
+     print "ENTER TWO-LETTER COUNTRY CODE:\n";
+  }
+  my $choice=<>;
+  chomp($choice);
+  if ($choice ne '') {
+    if (&Locale::Country::code2country(lc($choice))) {
+      open(OUT,'>>/tmp/loncapa_updatequery.out');
+      print(OUT 'country'."\t".uc($choice)."\n");
+      close(OUT);
+      $country=uc($choice);
+      $flag=1;
+    } else {
+      print "Invalid input -- a valid two letter country code is required\n";
+    }
+  } elsif (($choice eq '') && ($posscountry ne '')) {
+    open(OUT,'>>/tmp/loncapa_updatequery.out');
+    print(OUT 'country'."\t".$posscountry."\n");
+    close(OUT);
+    $country = $posscountry;
+    $flag = 1;
+  } else {
+    print "Invalid input -- a country code is required\n";
+  }
+}
+
+$flag=0;
+# get State or Province
+while (!$flag) {
+  print(<<END);
+
+ENTER STATE OR PROVINCE NAME:
+END
+
+  my $choice=<>;
+  chomp($choice);
+  if ($choice ne '') {
+    open(OUT,'>>/tmp/loncapa_updatequery.out');
+    print(OUT 'state'."\t".$choice."\n");
+    close(OUT);
+    $state=$choice;
+    $flag=1;
+  }
+  else {
+    print "Invalid input (a state or province name is required).\n";
+  }
+}
+
+$flag=0;
+# get City
+while (!$flag) {
+  print(<<END);
+
+ENTER CITY NAME:
+END
+
+  my $choice=<>;
+  chomp($choice);
+  if ($choice ne '') {
+    open(OUT,'>>/tmp/loncapa_updatequery.out');
+    print(OUT 'city'."\t".$choice."\n");
+    close(OUT);
+    $city=$choice;
+    $flag=1;
+  }
+  else {
+    print "Invalid input (a city is required).\n";
+  }
+}
+
+$flag=0;
+while (!$flag) {
+  print(<<END);
+
+The domain description, country, state and city will be
+used in the SSL certificates
+ 
+1) Domain Description: $domainDescription
+2) Country: $country
+3) State or Province: $state
+4) City: $city
+5) Everything is correct up above 
+
+ENTER A CHOICE OF 1-4 TO CHANGE, otherwise ENTER 5:
+END
+  my $choice=<>;
+  chomp($choice);
+  if ($choice == 1) {
+    print(<<END);
+1) Domain Description: $domainDescription
+ENTER NEW VALUE 
+END
+    my $choice2=<>;
+    chomp($choice2);
+    $domainDescription=$choice2;
+  }
+  elsif ($choice == 2) {
+    print(<<END);
+2) Country: $country
+ENTER NEW VALUE (this should be a two-character code, e,g, US, CA, DE)
+END
+    my $choice2=<>;
+    chomp($choice2);
+    $country = uc($choice2); 
+  }
+  elsif ($choice == 3) {
+    print(<<END);
+3) State or Province: $state
+ENTER NEW VALUE:
+END
+    my $choice2=<>;
+    chomp($choice2);
+    $state=$choice2;
+  }
+  elsif ($choice == 4) {
+    print(<<END);
+4) City: $city
+ENTER NEW VALUE:
+END
+    my $choice2=<>;
+    chomp($choice2);
+    $city=$choice2;
+  } elsif ($choice == 5) {
+    $flag=1;
+    $state =~ s{/}{ }g;
+    $city =~ s{/}{ }g;
+    $domainDescription =~ s{/}{ }g;
+  } else {
+    print "Invalid input.\n";
+  }
+}
+
+my $perlvarref = &get_static_config();
+if (ref($perlvarref) eq 'HASH') {
+  my ($certsdir,$privkey,$connectcsr,$replicatecsr);
+  $certsdir = $perlvarref->{'lonCertificateDirectory'};
+  $privkey = $perlvarref->{'lonnetPrivateKey'};  
+  $connectcsr = $perlvarref->{'lonnetCertificate'};
+  $connectcsr =~ s/\.pem$/.csr/;
+  $replicatecsr = $perlvarref->{'lonnetHostnameCertificate'};
+  $replicatecsr =~ s/\.pem$/.csr/;
+
+  print(<<END);
+
+****** SSL Certificates *****
+
+You need to provide a password to be used for the openssl key which
+will be stored in $certsdir, and will be used when creating two
+certificate signing requests: $connectcsr and $replicatecsr
+
+END
+
+  my $sslkeypass;
+  $flag=0;
+# get Password for SSL key
+  while (!$flag) {
+    $sslkeypass = &make_passphrase();
+    if ($sslkeypass) {
+      $flag = 1;
+    } else {
+      print "Invalid input (a password is required for the SSL key).\n";
+    }
+  }
+
+  if ($certsdir && $privkey) {
+    my $connectsubj = "/C=$country/ST=$state/O=$domainDescription/L=$city/CN=$lonHostID/OU=LONCAPA/emailAddress=$lonAdmEMail";
+    my $replicatesubj = "/C=$country/ST=$state/O=$domainDescription/L=$city/CN=internal-$desiredhostname/OU=LONCAPA/emailAddress=$lonAdmEMail";
+
+# generate SSL key
+# generate SSL csr for hostID
+# generate SSL csr for internal hostname
+
+    if (-f "$certsdir/lonKey.enc") {
+        my $mode = 0600;
+        chmod $mode, "$certsdir/lonKey.enc";
+    }
+    open(PIPE,"openssl genrsa -des3 -passout pass:$sslkeypass -out $certsdir/lonKey.enc 2048 2>&1 |");
+    close(PIPE);
+    if (-f "$certsdir/$privkey") {
+        my $mode = 0600;
+        chmod $mode, "$certsdir/$privkey";
+    }
+    open(PIPE,"openssl rsa -in $certsdir/lonKey.enc -passin pass:$sslkeypass -out $certsdir/$privkey -outform PEM |");
+    close(PIPE);
+    if ($connectcsr) {
+        open(PIPE,"openssl req -key $certsdir/lonKey.enc -passin pass:$sslkeypass -new -batch -subj \"$connectsubj\" -out $certsdir/$connectcsr |");
+        close(PIPE);
+    }
+    if ($replicatecsr) { 
+        open(PIPE,"openssl req -key $certsdir/lonKey.enc -passin pass:$sslkeypass -new -batch -subj \"$replicatesubj\" -out $certsdir/$replicatecsr |");
+        close(PIPE);
+    }
+    if (-f "$certsdir/lonKey.enc") {
+        my $mode = 0400;
+        chmod $mode, "$certsdir/lonKey.enc";
+    }
+    if (-f "$certsdir/$privkey") {
+        my $mode = 0400;
+        chmod $mode, "$certsdir/$privkey";
+    }
+  }
+
+  my $camail;
+  if ($lonCluster eq 'production' || $lonCluster eq 'development') {
+    $camail = $perlvarref->{'SSLEmail'};
+  } else {
+    $flag=0;
+# get Certificate Authority E-mail 
+    while (!$flag) {
+      print(<<END);
+
+ENTER EMAIL ADDRESS TO SEND CERTIFICATE SIGNING REQUESTS
+END
+
+      my $choice=<>;
+      chomp($choice);
+      if ($choice ne '') {
+        open(OUT,'>>/tmp/loncapa_updatequery.out');
+        print(OUT 'Certificate Authority Email Address'."\t".$choice."\n");
+        close(OUT);
+        $camail=$choice;
+        $flag=1;
+      } else {
+        print "Invalid input (an email address is required).\n";
+      }
+    }
+  }
+  if ($camail) {
+    my $subj;
+    if (-e "$certsdir/$connectcsr") { 
+        $subj = "Certificate Request ($lonHostID)";
+        print(&send_mail($desiredhostname,$camail,$subj,"$certsdir/$connectcsr"));
+    }
+    if (-e "$certsdir/$replicatecsr") {
+        $subj = "Certificate Request (internal-$desiredhostname)";
+        print(&send_mail($desiredhostname,$camail,$subj,"$certsdir/$replicatecsr"));
+    }
+  }
+}
+
 # update loncapa.conf
 my $confdir = '/etc/httpd/conf/';
 if ('<DIST />' eq 'sles10' || '<DIST />' eq 'sles11' || '<DIST />' eq 'sles12' || '<DIST />' eq 'suse10.1' || '<DIST />' eq 'suse10.2' || '<DIST />' eq 'suse10.3' || '<DIST />' eq 'suse11.1' || '<DIST />' eq 'suse11.2' || '<DIST />' eq 'suse11.3' || '<DIST />' eq 'suse11.4' || '<DIST />' eq 'suse12.1' || '<DIST />' eq 'suse12.2' || '<DIST />' eq 'suse12.3' || '<DIST />' eq 'suse13.1' || '<DIST />' eq 'suse13.2' || '<DIST />' eq 'debian5' || '<DIST />' eq 'debian6' || '<DIST />' eq 'ubuntu6' || '<DIST />' eq 'ubuntu8' || '<DIST />' eq 'ubuntu10' || '<DIST />' eq 'ubuntu12' || '<DIST />' eq 'ubuntu14' || '<DIST />' eq 'ubuntu16') {
@@ -742,6 +1207,7 @@
     push(@hosts_files,'/home/httpd/lonTabs/hosts.tab',
          '/home/httpd/lonTabs/dns_hosts.tab');
 
+    my @poss_hosts_files = @hosts_files;
     if (!$domainDescription) {
 	foreach my $file (@domain_files) {
 	    open(IN,'<'.$file);
@@ -795,6 +1261,7 @@
         }
     }
 
+    my (%hostnames,%protocols);
     while(!$primaryLibServer && (@hosts_files || @domain_files)) {
 	my $file = shift(@domain_files);
         open(IN,'<'.$file);
@@ -809,8 +1276,9 @@
 	$file = shift(@hosts_files);
 	open(IN,'<'.$file);
 	while(my $line = <IN>) {
-	    if ($line =~ /^([^\:]+)\:\Q$perlvar{'lonDefDomain'}\E\:library\:/) {
+	    if ($line =~ /^([^\:]+)\:\Q$perlvar{'lonDefDomain'}\E\:library\:([^\:]+)/) {
 		push(@libservers,$1);
+                $hostnames{$1} = $2;
 	    }
 	}
 	# make list unique
@@ -820,12 +1288,204 @@
 	    $primaryLibServer = $libservers[0];
 	}
     }
+
+# get hostname of primaryLibServer
+    my ($primary_hostname,$primary_protocol);
+    if ($primaryLibServer) {
+        if ($hostnames{$primaryLibServer}) {
+            $primary_hostname = $hostnames{$primaryLibServer};
+            $primary_protocol = $protocols{$primaryLibServer};
+        } else {
+            foreach my $file (@poss_hosts_files) {
+                open(IN,'<'.$file);
+                while (my $line = <IN>) {
+                    if ($line =~ /^([^\:]+)\:\Q$perlvar{'lonDefDomain'}\E\:library\:([^\:]+):(https?)/) {
+                        if ($1 eq $primaryLibServer) {
+                            $primary_hostname = $2;
+                            $primary_protocol = $3;
+                            last;
+                        }
+                    }
+                }
+                close(IN);
+                last if ($primary_hostname);
+            }
+        }
+    }
    
 # implement editing logic below, interactively
-# update loncapa.conf until 15 is entered
+# update loncapa.conf until 17 is entered
 
 my $flag=0;
 
+#
+# Changes to 5, 6, and 14 not supported if configuration.db set on primary library server.
+# (requires either this machine to be primary library server or for LON-CAPA and Apache
+# to be running on primary library server.
+#
+
+my ($isprimary,$domconf,$url,$gotdomconf,$adminmail,$supportmail,$connectssl,%setbygui);
+if ($primaryLibServer eq $perlvar{'lonHostID'}) {
+    $isprimary = 1;
+} else {
+    unless ($primary_protocol eq 'https') {
+        $primary_protocol = 'http';
+    } 
+    $url = $primary_protocol.'://'.$primary_hostname.'/cgi-bin/listdomconfig.pl';
+}
+my $domconf = &get_domain_config($perlvar{'lonDefDomain'},$isprimary,$url,\%perlvarstatic);
+if (ref($domconf)) {
+    $gotdomconf = 1;
+    if (ref($domconf->{'contacts'}) eq 'HASH') {
+        if (exists($domconf->{'contacts'}->{'adminemail'})) {
+            $adminmail = $domconf->{'contacts'}->{'adminemail'};
+        }
+        if (exists($domconf->{'contacts'}->{'supportemail'})) {
+            $supportmail = $domconf->{'contacts'}->{'supportemail'};
+        }
+    }
+    if (ref($domconf->{'ssl'}) eq 'HASH') {
+        if (ref($domconf->{'ssl'}->{'connect'}) eq 'HASH') {       
+            my ($sslreq,$sslnoreq);
+            my %contypes; 
+            foreach my $type ('dom','intdom','other') {
+                my $key;
+                if ($domconf->{'ssl'}->{'connect'}->{$type} eq 'req') {
+                    $key = 'yes';
+                } else {
+                    $key = 'no';
+                }
+                if ($type eq 'dom') {
+                    $contypes{$key} .= ' own domain,';
+                } elsif ($type eq 'intdom') {
+                    $contypes{$key} .= ' own institution,';
+                } elsif ($type eq 'other') { 
+                    $contypes{$key} .= ' other domains,';
+                }
+            }
+            foreach my $key (sort(keys(%contypes))) {
+                $contypes{$key} =~ s/^\s//;
+                $contypes{$key} =~ s/,$//;
+                if ($key eq 'yes') {
+                    $connectssl .= ' Yes ('.$contypes{$key}.'),';
+                } elsif ($key eq 'no') {
+                    $connectssl = ' No ('.$contypes{$key}.')';
+                }
+                $connectssl =~ s/,$//;
+            }
+        }
+    }
+}
+if ($connectssl) {
+    $setbygui{'securestatus'} = 1;
+    $securestatus = 'Set by domain configuration via web GUI. Currently: '.$connectssl; 
+}
+if ($adminmail) {
+    $adminmail = 'Set by domain configuration via web GUI. Currently: '.$adminmail;
+    $setbygui{'lonAdmEMail'} = 1;
+} else {
+    $adminmail = $perlvar{'lonAdmEMail'};
+}
+if ($supportmail) {
+    $supportmail = 'Set by domain configuration via web GUI. Currently: '.$supportmail;
+    $setbygui{'lonSupportEMail'} = 1;
+} else {
+    $supportmail = $perlvar{'lonSupportEMail'};
+}
+
+print "\nRetrieving status information for SSL key and certificates ...\n\n";
+my ($lonhostcertstatus,$lonhostnamecertstatus,$lonkeystatus);
+my $currcerts = &LONCAPA::SSL::print_certstatus({$perlvar{'lonHostID'} => 1,},'text','cgi');
+chomp($currcerts);
+my %sslstatus;
+
+if ($currcerts eq "$perlvar{'lonHostID'}:error") {
+    print "No information available for SSL certificates\n";
+    $sslstatus{'key'} = -1;
+    $sslstatus{'host'} = -1;
+    $sslstatus{'hostname'} = -1;
+    $sslstatus{'ca'} = -1;
+    $lonkeystatus = 'unknown status';
+    $lonhostcertstatus = 'unknown status';
+    $lonhostnamecertstatus = 'unknown status';
+} else {
+    my %sslnames = (
+                      key      => 'lonnetPrivateKey',
+                      host     => 'lonnetCertificate',
+                      hostname => 'lonnetHostnameCertificate',
+                      ca       => 'lonnetCertificateAuthority',
+                   );
+    my %ssldesc = (
+                    key      => 'Private Key',
+                    host     => 'Connections Certificate',
+                    hostname => 'Replication Certificate',
+                    ca       => 'LON-CAPA CA Certificate',
+                  );
+    my ($lonhost,$info) = split(/\:/,$currcerts,2);
+    if ($lonhost eq $perlvar{'lonHostID'}) {
+        my @items = split(/\&/,$info);
+        foreach my $item (@items) {
+            my ($key,$value) = split(/=/,$item,2);
+            my @data = split(/,/,$value);
+            if (grep(/^\Q$key\E$/,keys(%sslnames))) {
+                if (lc($data[0]) eq 'yes') { 
+                    print "$ssldesc{$key} $perlvarstatic{$sslnames{$key}} available with status = $data[1]\n";
+                    if ($key eq 'key') {
+                        $lonkeystatus = "status: $data[1]"; 
+                        if ($data[1] =~ /ok$/) {
+                            $sslstatus{$key} = 1;
+                        } 
+                    } else {
+                        if ($data[1] eq 'Expired') {
+                            $sslstatus{$key} = 2;
+                        } else {
+                            $sslstatus{$key} = 1;
+                        }
+                        if ($key eq 'host') {
+                            $lonhostcertstatus = "status: $data[1]";
+                        } elsif ($key eq 'hostname') {
+                            $lonhostnamecertstatus = "status: $data[1]";
+                        }
+                    }
+                } else {
+                    $sslstatus{$key} = 0;
+                    print "$ssldesc{$key} $perlvarstatic{$sslnames{$key}} not available\n";
+                    if (($key eq 'host') || ($key eq 'hostname')) {
+                        my $csr = $perlvarstatic{$sslnames{$key}};
+                        $csr =~s /\.pem$/.csr/;
+                        my $csrstatus;
+                        if (-e "$perlvarstatic{'lonCertificateDirectory'}/$csr") {
+                            open(PIPE,"openssl req -text -noout -verify -in $perlvarstatic{'lonCertificateDirectory'}/$csr 2>&1 |");
+                            while(<PIPE>) {
+                                chomp();
+                                $csrstatus = $_;
+                                last;
+                            }
+                            close(PIPE);
+                            print "Certificate signing request for $ssldesc{$key} available with status = $csrstatus\n\n";
+                            if ($key eq 'host') {
+                                $lonhostcertstatus = 'awaiting signature';
+                            } else {
+                                $lonhostnamecertstatus = 'awaiting signature';
+                            }
+                            $sslstatus{$key} = 3;
+                        } else {
+                            print "No certificate signing request available for $ssldesc{$key}\n\n";
+                            if ($key eq 'host') {
+                                $lonhostcertstatus = 'still needed';
+                            } else {
+                                $lonhostnamecertstatus = 'still needed';
+                            }
+                        }
+                    } elsif ($key eq 'key') {
+                        $lonkeystatus = 'still needed';
+                    }
+                }
+            }
+        }
+    }
+}
+
 while (!$flag) {
   print(<<END);
 
@@ -835,17 +1495,20 @@
  2) Domain Description: $domainDescription
  3) Machine Name: $perlvar{'lonHostID'}
  4) ID of primary library server for domain: $primaryLibServer
- 5) Server Administrator's E-mail Address: $perlvar{'lonAdmEMail'}
- 6) Support E-mail Address: $perlvar{'lonSupportEMail'}
+ 5) Server Administrator's E-mail Address: $adminmail
+ 6) Support E-mail Address: $supportmail
  7) Web Server Protocol (http or https): $protocol 
  8) Internet Domain Name: $intdom 
  9) Hostname: $desiredhostname
 10) Role: $perlvar{'lonRole'}
-11) Cache Expiration Time: $perlvar{'lonExpire'}
+11) Cache Expiration Time: $perlvar{'lonExpire'} (seconds)
 12) Server Load: $perlvar{'lonLoadLim'}
 13) User Load: $perlvar{'lonUserLoadLim'}
-14) Allow only secure connections: $securestatus 
-15) Everything is correct up above
+14) Allow only secure connections: $securestatus
+15) Private Key for SSL: $lonkeystatus
+16) SSL Certificate for LON-CAPA server connections: $lonhostcertstatus
+17) SSL Certificate for Content Replication: $lonhostnamecertstatus
+18) Everything is correct up above
 END
 
 my @error;
@@ -909,9 +1572,17 @@
 }
 
 
+my ($certsdir,$privkey,$connectcsr,$replicatecsr);
+$certsdir = $perlvarstatic{'lonCertificateDirectory'};
+$privkey = $perlvarstatic{'lonnetPrivateKey'};
+$connectcsr = $perlvarstatic{'lonnetCertificate'};
+$connectcsr =~ s/\.pem$/.csr/;
+$replicatecsr = $perlvarstatic{'lonnetHostnameCertificate'};
+$replicatecsr =~ s/\.pem$/.csr/;
+
 if (@error) { print "\n*** ERRORS: \n\t".join("\n\t", at error)."\n"; }
   print(<<END);
-ENTER A CHOICE OF 1-14 TO CHANGE, otherwise ENTER 15:
+ENTER A CHOICE OF 1-17 TO CHANGE, otherwise ENTER 18:
 END
 my $choice=<>;
 chomp($choice);
@@ -964,22 +1635,36 @@
     $primaryLibServer=$choice2;
   }
   elsif ($choice==5) {
-  print(<<END);
+    if ($setbygui{'lonAdmEMail'}) {
+      print(<<END);
+5) Server Administrator's E-mail Address: $adminmail
+Use the web GUI (as domain coordinator) to make changes after completing the UPDATE.
+END
+    } else {
+      print(<<END);
 5) Server Administrator's E-mail Address: $perlvar{'lonAdmEMail'}
 ENTER NEW VALUE:
 END
-    my $choice2=<>;
-    chomp($choice2);
-    $perlvar{'lonAdmEMail'}=$choice2;
+      my $choice2=<>;
+      chomp($choice2);
+      $perlvar{'lonAdmEMail'}=$choice2;
+    }
   }
   elsif ($choice==6) {
-  print(<<END);
+    if ($setbygui{'lonAdmEMail'}) {
+      print(<<END);
+6) Support E-mail Address: $supportmail
+Use the web GUI (as domain coordinator) to make changes after completing the UPDATE.
+END
+    } else {    
+      print(<<END);
 6) Support E-mail Address: $perlvar{'lonSupportEMail'}
 ENTER NEW VALUE:
 END
-    my $choice2=<>;
-    chomp($choice2);
-    $perlvar{'lonSupportEMail'}=$choice2;
+      my $choice2=<>;
+      chomp($choice2);
+      $perlvar{'lonSupportEMail'}=$choice2;
+    }
   }
   elsif ($choice==7) {
   print(<<END);
@@ -1051,7 +1736,13 @@
     $perlvar{'lonUserLoadLim'}=$choice2;
   }
   elsif ($choice==14) {
-  print(<<END);
+    if ($setbygui{'securestatus'}) {
+      print(<<END);
+14) Allow only secure connections: $securestatus
+Use the web GUI (as domain coordinator) to make changes after completing the UPDATE.
+END
+    } else {
+      print(<<END);
 14) Allow only secure connections: $securestatus 
 The Lon-CAPA communication daemons lonc and lond can be configured to
 allow only secure connections by default.
@@ -1066,23 +1757,63 @@
 4) allow insecure connections
 ENTER NEW VALUE (currently $securenum):
 END
-    my $choice2=<>;
-    chomp($choice2);
-    if      ($choice2 eq '1') {
-	$perlvar{'loncAllowInsecure'}=0;$perlvar{'londAllowInsecure'}=0;
-    } elsif ($choice2 eq '2') {
-	$perlvar{'loncAllowInsecure'}=0;$perlvar{'londAllowInsecure'}=1;
-    } elsif ($choice2 eq '3') {
-	$perlvar{'loncAllowInsecure'}=1;$perlvar{'londAllowInsecure'}=0;
-    } elsif ($choice2 eq '4') {
-	$perlvar{'loncAllowInsecure'}=1;$perlvar{'londAllowInsecure'}=1;
+      my $choice2=<>;
+      chomp($choice2);
+      if      ($choice2 eq '1') {
+	  $perlvar{'loncAllowInsecure'}=0;$perlvar{'londAllowInsecure'}=0;
+      } elsif ($choice2 eq '2') {
+	  $perlvar{'loncAllowInsecure'}=0;$perlvar{'londAllowInsecure'}=1;
+      } elsif ($choice2 eq '3') {
+	  $perlvar{'loncAllowInsecure'}=1;$perlvar{'londAllowInsecure'}=0;
+      } elsif ($choice2 eq '4') {
+	  $perlvar{'loncAllowInsecure'}=1;$perlvar{'londAllowInsecure'}=1;
+      }
+      ($securestatus,$securenum)=&securesetting(%perlvar);
     }
-    ($securestatus,$securenum)=&securesetting(%perlvar);
-  }
-  elsif (($choice==15) && (!@error)) {
+  } elsif ($choice==15) {
+      #$sslstatus{'key'};
+      print(<<END);
+15) Private Key for SSL: $lonkeystatus
+
+POSSIBLE CHOICES:
+1) overwrite existing key
+2) create new key for use later
+3) make no change
+ENTER NEW VALUE
+END
+      my $choice2=<>;
+      chomp($choice2);
+  } elsif ($choice==16) {
+      #$sslstatus{'host'};
+      print(<<END);
+16) SSL Certificate for LON-CAPA server connections: $lonhostcertstatus
+
+POSSIBLE CHOICES:
+1) create new certificate signing request with new key
+2) create new certificate signing request with existing key
+3) resend current certificate signing request
+4) make no change
+ENTER NEW VALUE
+END
+      my $choice2=<>;
+      chomp($choice2);
+  } elsif ($choice==17) {
+      #$sslstatus{'hostname'}
+      print(<<END);
+17) SSL Certificate for Content Replication: $lonhostnamecertstatus
+
+POSSIBLE CHOICES:
+1) create new certificate signing request with new key
+2) create new certificate signing request with existing key
+3) resend current certificate signing request
+4) make no change
+ENTER NEW VALUE
+END
+      my $choice2=<>;
+      chomp($choice2);
+  } elsif (($choice==18) && (!@error)) {
     $flag=1;
-  }
-  else {
+  } else {
     print "Invalid input.\n";
   }
 }


More information about the LON-CAPA-cvs mailing list