[LON-CAPA-cvs] cvs: doc /loncapafiles updatequery.piml
raeburn
raeburn at source.lon-capa.org
Thu May 18 20:56:35 EDT 2017
raeburn Fri May 19 00:56:35 2017 EDT
Modified files:
/doc/loncapafiles updatequery.piml
Log:
- Existing installations can create new SSL key and/or certificate signing
requests for (a) LON-CAPA SSL certificates (Common Name is HostID) used
for exchange of the cipher key via an SSL channel, and (b) Apache/SSL
client certificate used for content replication between servers via LWP.
-------------- next part --------------
Index: doc/loncapafiles/updatequery.piml
diff -u doc/loncapafiles/updatequery.piml:1.87 doc/loncapafiles/updatequery.piml:1.88
--- doc/loncapafiles/updatequery.piml:1.87 Tue May 16 17:33:33 2017
+++ doc/loncapafiles/updatequery.piml Fri May 19 00:56:34 2017
@@ -1,6 +1,6 @@
<!-- updatequery.piml -->
-<!-- $Id: updatequery.piml,v 1.87 2017/05/16 17:33:33 raeburn Exp $ -->
+<!-- $Id: updatequery.piml,v 1.88 2017/05/19 00:56:34 raeburn Exp $ -->
<!--
@@ -44,21 +44,20 @@
use Term::ReadKey;
use Locale::Country;
- print(<<END);
-
-
-*********************************************
-*********************************************
-**** ****
-**** LON-CAPA SYSTEM INFORMATION REQUEST ****
-**** ****
-**** Please respond to the choices below ****
-**** ****
-*********************************************
-*********************************************
-
-END
-#sleep(3);
+sub get_new_sslkeypass {
+ my $sslkeypass;
+ my $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";
+ }
+ }
+ return $sslkeypass;
+}
sub get_static_config {
# get LCperlvars from loncapa_apache.conf
@@ -135,7 +134,7 @@
my $maxtries = 10;
my $trial = 0;
while ((!$got_passwd) && ($trial < $maxtries)) {
- $firstpass = &get_password('Enter password');
+ $firstpass = &get_password('Enter a password for the SSL key (at least 6 characters long)');
if (length($firstpass) < 6) {
print('Password too short.'."\n".
'Please choose a password with at least six characters.'."\n".
@@ -213,6 +212,454 @@
return;
}
+sub mail_csr {
+ my ($types,$lonCluster,$lonHostID,$desiredhostname,$certsdir,$connectcsr,$replicatecsr,$perlvarref) = @_;
+ my ($camail,$flag);
+ 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 (($types eq 'both') || ($types = 'host')) {
+ if (-e "$certsdir/$connectcsr") {
+ $subj = "Certificate Request ($lonHostID)";
+ print(&send_mail($desiredhostname,$camail,$subj,"$certsdir/$connectcsr"));
+ }
+ }
+ if (($types eq 'both') || ($types = 'hostname')) {
+ if (-e "$certsdir/$replicatecsr") {
+ $subj = "Certificate Request (internal-$desiredhostname)";
+ print(&send_mail($desiredhostname,$camail,$subj,"$certsdir/$replicatecsr"));
+ }
+ }
+ }
+}
+
+sub ssl_info {
+ 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
+}
+
+sub get_country {
+ my ($desiredhostname) = @_;
+# get Country
+ my ($posscountry,$country);
+ 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);
+ }
+ }
+
+ my $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";
+ }
+ }
+ return $country;
+}
+
+sub get_state {
+# get State or Province
+ my $flag=0;
+ my $state = '';
+ 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";
+ }
+ }
+ return $state;
+}
+
+sub get_city {
+# get City
+ my $flag=0;
+ my $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";
+ }
+ }
+ return $city;
+}
+
+sub confirm_locality {
+ my ($domainDescription,$country,$state,$city) = @_;
+ my $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";
+ }
+ }
+ return ($domainDescription,$country,$state,$city);
+}
+
+sub make_key {
+ my ($certsdir,$privkey,$sslkeypass) = @_;
+# generate SSL key
+ if ($certsdir && $privkey) {
+ 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 (-f "$certsdir/lonKey.enc") {
+ my $mode = 0400;
+ chmod $mode, "$certsdir/lonKey.enc";
+ }
+ if (-f "$certsdir/$privkey") {
+ my $mode = 0400;
+ chmod $mode, "$certsdir/$privkey";
+ }
+ } else {
+ print "Key creation failed. Missing one or more of: certificates directory, key name\n";
+ }
+}
+
+sub encrypt_key {
+ my ($certsdir,$privkey,$sslkeypass) = @_;
+ if ($certsdir && $privkey) {
+ if ((-f "$certsdir/$privkey") && (!-f "$certsdir/lonKey.enc")) {
+ open(PIPE,"openssl rsa -des3 -in $certsdir/$privkey -out $certsdir/lonKey.enc |");
+ }
+ }
+ return;
+}
+
+sub make_host_csr {
+ my ($certsdir,$sslkeypass,$connectcsr,$connectsubj) = @_;
+# generate SSL csr for hostID
+ if ($certsdir && $connectcsr && $connectsubj) {
+ open(PIPE,"openssl req -key $certsdir/lonKey.enc -passin pass:$sslkeypass -new -batch -subj \"$connectsubj\" -out $certsdir/$connectcsr |");
+ close(PIPE);
+ } else {
+ print "Creation of certificate signing request failed. Missing one or more of: certificates directory, CSR name, or locality information.\n";
+ }
+}
+
+sub make_hostname_csr {
+ my ($certsdir,$sslkeypass,$replicatecsr,$replicatesubj) = @_;
+# generate SSL csr for internal hostname
+ if ($certsdir && $replicatecsr && $replicatesubj) {
+ open(PIPE,"openssl req -key $certsdir/lonKey.enc -passin pass:$sslkeypass -new -batch -subj \"$replicatesubj\" -out $certsdir/$replicatecsr |");
+ close(PIPE);
+ } else {
+ print "Creation of certificate signing request failed. Missing one or more of: certificates directory, CSR name, or locality information.\n";
+ }
+}
+
+sub securesetting {
+ my (%perlvar) = @_;
+ my ($securestatus,$securenum);
+ if (($perlvar{'loncAllowInsecure'}) && ($perlvar{'londAllowInsecure'})) {
+ $securenum = 4;
+ $securestatus = 'Allow insecure connections - inbound and outbound';
+ } elsif (($perlvar{'loncAllowInsecure'}) && (!$perlvar{'londAllowInsecure'})) {
+ $securenum = 3;
+ $securestatus = 'Outbound: allow insecure connections; Inbound: secure only';
+ } elsif ((!$perlvar{'loncAllowInsecure'}) && ($perlvar{'londAllowInsecure'})) {
+ $securenum = 2;
+ $securestatus = 'Outbound: secure connections only; Inbound: allow insecure';
+ } elsif ((!$perlvar{'loncAllowInsecure'}) && (!$perlvar{'londAllowInsecure'})) {
+ $securenum = 1;
+ $securestatus = 'Secure connections only - inbound and outbound ';
+ }
+ return ($securestatus,$securenum);
+}
+
+sub get_sslnames {
+ my %sslnames = (
+ key => 'lonnetPrivateKey',
+ host => 'lonnetCertificate',
+ hostname => 'lonnetHostnameCertificate',
+ ca => 'lonnetCertificateAuthority',
+ );
+ return %sslnames;
+}
+
+sub get_ssldesc {
+ my %ssldesc = (
+ key => 'Private Key',
+ host => 'Connections Certificate',
+ hostname => 'Replication Certificate',
+ ca => 'LON-CAPA CA Certificate',
+ );
+ return %ssldesc;
+}
+
+sub get_cert_status {
+ my ($lonHostID,$perlvarstatic) = @_;
+ my $currcerts = &LONCAPA::SSL::print_certstatus({$lonHostID => 1,},'text','cgi');
+ my ($lonkeystatus,$lonhostcertstatus,$lonhostnamecertstatus,%sslstatus);
+ my $output = '';
+ if ($currcerts eq "$lonHostID:error") {
+ $output .= "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 = &get_sslnames();
+ my %ssldesc = &get_ssldesc();
+ my ($lonhost,$info) = split(/\:/,$currcerts,2);
+ if ($lonhost eq $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') {
+ $output .= "$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 {
+ my $setstatus;
+ if (($key eq 'host') || ($key eq 'hostname')) {
+ if ($data[1] eq 'otherkey') {
+ $sslstatus{$key} = 4;
+ $setstatus = 1;
+ if ($key eq 'host') {
+ $lonhostcertstatus = "status: created with different key";
+ } elsif ($key eq 'hostname') {
+ $lonhostnamecertstatus = "status: created with different key";
+ }
+ } elsif ($data[1] eq 'nokey') {
+ $sslstatus{$key} = 5;
+ $setstatus = 1;
+ if ($key eq 'host') {
+ $lonhostcertstatus = "status: created with missing key";
+ } elsif ($key eq 'hostname') {
+ $lonhostnamecertstatus = "status: created with missing key";
+ }
+ }
+ }
+ unless ($setstatus) {
+ if ($data[1] eq 'expired') {
+ $sslstatus{$key} = 2;
+ } elsif ($data[1] eq 'future') {
+ $sslstatus{$key} = 3;
+ } else {
+ $sslstatus{$key} = 1;
+ }
+ if ($key eq 'host') {
+ $lonhostcertstatus = "status: $data[1]";
+ } elsif ($key eq 'hostname') {
+ $lonhostnamecertstatus = "status: $data[1]";
+ }
+ }
+ }
+ } else {
+ $sslstatus{$key} = 0;
+ $output .= "$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);
+ $output .= "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 {
+ $output .= "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';
+ }
+ }
+ }
+ }
+ }
+ }
+ return ($output,$lonkeystatus,$lonhostcertstatus,$lonhostnamecertstatus,\%sslstatus);
+}
+
+ print(<<END);
+
+
+*********************************************
+*********************************************
+**** ****
+**** LON-CAPA SYSTEM INFORMATION REQUEST ****
+**** ****
+**** Please respond to the choices below ****
+**** ****
+*********************************************
+*********************************************
+
+END
+#sleep(3);
+
</perlscript>
</file>
<file>
@@ -787,182 +1234,24 @@
}
}
-# get Country
-print(<<END);
+&ssl_info();
-****** Information about Country, State or Province and City *****
+$country = &get_country($desiredhostname);
-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.
+$state = &get_state();
-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.
+$city = &get_city();
-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);
- }
-}
+($domainDescription,$country,$state,$city) = &confirm_locality($domainDescription,$country,$state,$city);
-$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 $perlstaticref = &get_static_config();
+if (ref($perlstaticref) eq 'HASH') {
my ($certsdir,$privkey,$connectcsr,$replicatecsr);
- $certsdir = $perlvarref->{'lonCertificateDirectory'};
- $privkey = $perlvarref->{'lonnetPrivateKey'};
- $connectcsr = $perlvarref->{'lonnetCertificate'};
+ $certsdir = $perlstaticref->{'lonCertificateDirectory'};
+ $privkey = $perlstaticref->{'lonnetPrivateKey'};
+ $connectcsr = $perlstaticref->{'lonnetCertificate'};
$connectcsr =~ s/\.pem$/.csr/;
- $replicatecsr = $perlvarref->{'lonnetHostnameCertificate'};
+ $replicatecsr = $perlstaticref->{'lonnetHostnameCertificate'};
$replicatecsr =~ s/\.pem$/.csr/;
print(<<END);
@@ -975,92 +1264,26 @@
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";
- }
- }
+ my $sslkeypass = &get_new_sslkeypass();
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
+ &make_key($certsdir,$privkey,$sslkeypass);
# generate SSL csr for hostID
+ &make_host_csr($certsdir,$sslkeypass,$connectcsr,$connectsubj);
# generate SSL csr for internal hostname
+ &make_hostname_csr($certsdir,$sslkeypass,$replicatecsr,$replicatesubj);
+# mail csr files to certificate at lon-capa.org (production or dev clusters).
+ &mail_csr('both',$lonCluster,$lonHostID,$desiredhostname,$certsdir,$connectcsr,$replicatecsr,$perlstaticref);
- 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"));
+ } else {
+ print "Could not acquire standard names for SSL Certificate files from loncapa_apache.conf\n";
}
- }
+} else {
+ print "Could not acquire standard names for SSL Certificate files from loncapa_apache.conf\n";
}
# update loncapa.conf
@@ -1124,26 +1347,10 @@
<target dist='default'>/etc/httpd/conf/</target>
<target dist='sles10 sles11 sles12 suse10.1 suse10.2 suse10.3 suse11.1 suse11.2 suse11.3 suse11.4 suse12.1 suse12.2 suse12.3 suse13.1 suse13.2 debian5 debian6 ubuntu6 ubuntu8 ubuntu10 ubuntu12 ubuntu14 ubuntu16'>/etc/apache2/</target>
<perlscript mode='fg'>
-sub securesetting {
- my (%perlvar)=@_;
- my $securestatus='unknown';
- my $securenum='';
- if ( $perlvar{'loncAllowInsecure'}&& $perlvar{'londAllowInsecure'}) {
- $securestatus='no'; $securenum='4';
- } elsif ( $perlvar{'loncAllowInsecure'}&& !$perlvar{'londAllowInsecure'}) {
- $securestatus='lond'; $securenum='3';
- } elsif (!$perlvar{'loncAllowInsecure'}&& $perlvar{'londAllowInsecure'}) {
- $securestatus='lonc'; $securenum='2';
- } elsif (!$perlvar{'loncAllowInsecure'}&& !$perlvar{'londAllowInsecure'}) {
- $securestatus='yes (lond and lonc)'; $securenum='1';
- }
- return ($securestatus,$securenum);
-}
# read values from loncapa.conf
my $confdir = "<TARGET />";
my $filename='loncapa.conf';
my %perlvar;
-my ($securestatus,$securenum);
if (-e "$confdir$filename") {
open(CONFIG,'<'.$confdir.$filename) or
die("Can't read $confdir$filename");
@@ -1171,7 +1378,7 @@
unless ($perlvar{'loncAllowInsecure'} and $perlvar{'loncAllowInsecure'}!~/\{\[\[\[\[/) {
$perlvar{'loncAllowInsecure'}='1';
}
- ($securestatus,$securenum)=&securesetting(%perlvar);
+ my ($securestatus,$securenum)=&securesetting(%perlvar);
unless ($perlvar{'lonReceipt'} and $perlvar{'lonReceipt'}!~/\{\[\[\[\[/) {
my $lonReceipt='';
srand(time ^ $$ ^ unpack "%L*", `ps axww | gzip`);
@@ -1181,19 +1388,7 @@
}
$perlvar{'lonReceipt'}=$lonReceipt;
}
-my %perlvarstatic;
- if (-e "${confdir}loncapa_apache.conf") {
- open(CONFIG,'<'.$confdir.'loncapa_apache.conf') or
- die("Can't read ${confdir}loncapa_apache.conf");
- while (my $configline=<CONFIG>) {
- if ($configline =~ /^[^\#]*PerlSetVar/) {
- my ($unused,$varname,$varvalue)=split(/\s+/,$configline);
- chomp($varvalue);
- $perlvarstatic{$varname}=$varvalue;
- }
- }
- close(CONFIG);
- }
+ my $perlvarstatic = &get_static_config();
my (@hosts_files, @domain_files);
if ( $lonCluster ne 'existing') {
@@ -1314,14 +1509,14 @@
}
# implement editing logic below, interactively
-# update loncapa.conf until 17 is entered
+# update loncapa.conf until 18 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.
+# to be running on primary library server).
#
my ($isprimary,$domconf,$url,$gotdomconf,$adminmail,$supportmail,$connectssl,%setbygui);
@@ -1333,8 +1528,12 @@
}
$url = $primary_protocol.'://'.$primary_hostname.'/cgi-bin/listdomconfig.pl';
}
+
+my %sslnames = &get_sslnames();
+my %ssldesc = &get_ssldesc();
+
my $domconf = &get_domain_config($perlvar{'lonDefDomain'},$primaryLibServer,$isprimary,
- $url,\%perlvarstatic);
+ $url,$perlvarstatic);
if (ref($domconf)) {
$gotdomconf = 1;
if (ref($domconf->{'contacts'}) eq 'HASH') {
@@ -1376,7 +1575,7 @@
$currsetting =~ s/,$//;
}
if ($currsetting ne '') {
- $connectssl = $sslname{$connect}.' -- '.$currsetting.' | ';
+ $connectssl = $sslnames{$connect}.' -- '.$currsetting.' | ';
}
}
}
@@ -1401,96 +1600,12 @@
}
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 ($certinfo,$lonkeystatus,$lonhostcertstatus,$lonhostnamecertstatus,$sslref) =
+ &get_cert_status($perlvar{'lonHostID'},$perlvarstatic);
+print $certinfo;
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';
- }
- }
- }
- }
- }
+if (ref($sslref) eq 'HASH') {
+ %sslstatus = %{$sslref};
}
while (!$flag) {
@@ -1511,7 +1626,7 @@
11) Cache Expiration Time: $perlvar{'lonExpire'} (seconds)
12) Server Load: $perlvar{'lonLoadLim'}
13) User Load: $perlvar{'lonUserLoadLim'}
-14) Allow only secure connections: $securestatus
+14) LON-CAPA "internal" connections: $securestatus
15) Private Key for SSL: $lonkeystatus
16) SSL Certificate for LON-CAPA server connections: $lonhostcertstatus
17) SSL Certificate for Content Replication: $lonhostnamecertstatus
@@ -1580,11 +1695,11 @@
my ($certsdir,$privkey,$connectcsr,$replicatecsr);
-$certsdir = $perlvarstatic{'lonCertificateDirectory'};
-$privkey = $perlvarstatic{'lonnetPrivateKey'};
-$connectcsr = $perlvarstatic{'lonnetCertificate'};
+$certsdir = $perlvarstatic->{'lonCertificateDirectory'};
+$privkey = $perlvarstatic->{'lonnetPrivateKey'};
+$connectcsr = $perlvarstatic->{'lonnetCertificate'};
$connectcsr =~ s/\.pem$/.csr/;
-$replicatecsr = $perlvarstatic{'lonnetHostnameCertificate'};
+$replicatecsr = $perlvarstatic->{'lonnetHostnameCertificate'};
$replicatecsr =~ s/\.pem$/.csr/;
if (@error) { print "\n*** ERRORS: \n\t".join("\n\t", at error)."\n"; }
@@ -1655,10 +1770,11 @@
my $choice2=<>;
chomp($choice2);
$perlvar{'lonAdmEMail'}=$choice2;
+ $adminmail=$perlvar{'lonAdmEMail'};
}
}
elsif ($choice==6) {
- if ($setbygui{'lonAdmEMail'}) {
+ if ($setbygui{'lonSupportEMail'}) {
print(<<END);
6) Support E-mail Address: $supportmail
Use the web GUI (as domain coordinator) to make changes after completing the UPDATE.
@@ -1671,6 +1787,7 @@
my $choice2=<>;
chomp($choice2);
$perlvar{'lonSupportEMail'}=$choice2;
+ $supportmail=$perlvar{'lonSupportEMail'};
}
}
elsif ($choice==7) {
@@ -1778,23 +1895,37 @@
($securestatus,$securenum)=&securesetting(%perlvar);
}
} elsif ($choice==15) {
- if (($sslstatus{'key'} == 1) || ($sslstatus{'key'} == 2)) {
+ if ($sslstatus{'key'} == 1) {
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
+2) make no change
ENTER NEW VALUE
END
- } elsif ($sslstatus{'key'} == ) {
- my $choice2=<>;
- chomp($choice2);
+ my $choice2=<>;
+ chomp($choice2);
+ if ($choice2 eq '1') {
+ my $sslkeypass = &get_new_sslkeypass();
+ &make_key($certsdir,$privkey,$sslkeypass);
+ }
+ } elsif ($sslstatus{'key'} == 0) {
+ print(<<END);
+15) Private Key for SSL: $lonkeystatus
+END
+ my $sslkeypass = &get_new_sslkeypass();
+ &make_key($certsdir,$privkey,$sslkeypass);
+ print "\nRetrieving status information for SSL key and certificates ...\n\n";
+ ($certinfo,$lonkeystatus,$lonhostcertstatus,$lonhostnamecertstatus,$sslref) =
+ &get_cert_status($perlvar{'lonHostID'},$perlvarstatic);
+ if (ref($sslref) eq 'HASH') {
+ %sslstatus = %{$sslref};
+ }
+ }
} elsif ($choice==16) {
- if ($sslstatus{'key'} == 1) || ($sslstatus{'key'} == 2)) {
- #$sslstatus{'host'};
- print(<<END);
+ if (($sslstatus{'host'} == 1) || ($sslstatus{'host'} == 2) || ($sslstatus{'host'} == 3)) {
+ print(<<END);
16) SSL Certificate for LON-CAPA server connections: $lonhostcertstatus
POSSIBLE CHOICES:
@@ -1804,11 +1935,81 @@
4) make no change
ENTER NEW VALUE
END
- my $choice2=<>;
- chomp($choice2);
+
+ my $choice2=<>;
+ chomp($choice2);
+ if (($choice2 eq '1') || ($choice2 eq '2')) {
+ &ssl_info();
+ my $country = &get_country($desiredhostname);
+ my $state = &get_state();
+ my $city = &get_city();
+ my $connectsubj = "/C=$country/ST=$state/O=$domainDescription/L=$city/CN=$perlvar{'lonHostID'}/OU=LONCAPA/emailAddress=$adminmail";
+ ($domainDescription,$country,$state,$city) = &confirm_locality($domainDescription,$country,$state,$city);
+ my $sslkeypass;
+ if ($choice2 eq '1') {
+ $sslkeypass = &get_new_sslkeypass();
+ &make_key($certsdir,$privkey,$sslkeypass);
+ } elsif ($choice2 eq '2') {
+ $sslkeypass = &get_password('Enter existing password for SSL key');
+ &encrypt_key($certsdir,$privkey,$sslkeypass);
+ }
+ &make_host_csr($certsdir,$sslkeypass,$connectcsr,$connectsubj);
+ &mail_csr('host',$lonCluster,$perlvar{'lonHostID'},$desiredhostname,$certsdir,$connectcsr,$replicatecsr,$perlvarstatic);
+ print "\nRetrieving status information for SSL key and certificates ...\n\n";
+ ($certinfo,$lonkeystatus,$lonhostcertstatus,$lonhostnamecertstatus,$sslref) =
+ &get_cert_status($perlvar{'lonHostID'},$perlvarstatic);
+ if (ref($sslref) eq 'HASH') {
+ %sslstatus = %{$sslref};
+ }
+ } elsif ($choice2 eq '3') {
+ if (-e "$certsdir/$connectcsr") {
+ &mail_csr('host',$lonCluster,$perlvar{'lonHostID'},$desiredhostname,$certsdir,$connectcsr,$replicatecsr,$perlvarstatic);
+ }
+ }
+ } elsif (($sslstatus{'host'} == 0) || ($sslstatus{'host'} == 4) || ($sslstatus{'host'} == 5)) {
+ my $sslkeypass;
+ if ($sslstatus{'key'} == 1) {
+ 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) make no change
+ENTER NEW VALUE
+END
+ my $choice2=<>;
+ chomp($choice2);
+ if ($choice2 eq '1') {
+ $sslkeypass = &get_new_sslkeypass();
+ &make_key($certsdir,$privkey,$sslkeypass);
+ } elsif ($choice2 eq '2') {
+ $sslkeypass = &get_password('Enter existing password for SSL key');
+ &encrypt_key($certsdir,$privkey,$sslkeypass);
+ }
+ } else {
+ print(<<END);
+16) SSL Certificate for LON-CAPA server connections: $lonhostcertstatus
+END
+ $sslkeypass = &get_new_sslkeypass();
+ }
+ &ssl_info();
+ my $country = &get_country($desiredhostname);
+ my $state = &get_state();
+ my $city = &get_city();
+ my $connectsubj = "/C=$country/ST=$state/O=$domainDescription/L=$city/CN=$perlvar{'lonHostID'}/OU=LONCAPA/emailAddress=$adminmail";
+ &make_host_csr($certsdir,$sslkeypass,$connectcsr,$connectsubj);
+ &mail_csr('host',$lonCluster,$perlvar{'lonHostID'},$desiredhostname,$certsdir,$connectcsr,$replicatecsr,$perlvarstatic);
+ print "\nRetrieving status information for SSL key and certificates ...\n\n";
+ ($certinfo,$lonkeystatus,$lonhostcertstatus,$lonhostnamecertstatus,$sslref) =
+ &get_cert_status($perlvar{'lonHostID'},$perlvarstatic);
+ if (ref($sslref) eq 'HASH') {
+ %sslstatus = %{$sslref};
+ }
+ }
} elsif ($choice==17) {
- #$sslstatus{'hostname'}
- print(<<END);
+ if (($sslstatus{'hostname'} == 1) || ($sslstatus{'hostname'} == 2) || ($sslstatus{'hostname'} == 3)) {
+ print(<<END);
17) SSL Certificate for Content Replication: $lonhostnamecertstatus
POSSIBLE CHOICES:
@@ -1818,8 +2019,76 @@
4) make no change
ENTER NEW VALUE
END
- my $choice2=<>;
- chomp($choice2);
+ my $choice2=<>;
+ chomp($choice2);
+ if (($choice2 eq '1') || ($choice2 eq '2')) {
+ &ssl_info();
+ my $country = &get_country($desiredhostname);
+ my $state = &get_state();
+ my $city = &get_city();
+ my $replicatesubj = "/C=$country/ST=$state/O=$domainDescription/L=$city/CN=internal-$desiredhostname/OU=LONCAPA/emailAddress=$adminmail";
+ my $sslkeypass;
+ if ($choice2 eq '1') {
+ $sslkeypass = &get_new_sslkeypass();
+ &make_key($certsdir,$privkey,$sslkeypass);
+ } elsif ($choice2 eq '2') {
+ $sslkeypass = &get_password('Enter existing password for SSL key');
+ &encrypt_key($certsdir,$privkey,$sslkeypass);
+ }
+ &make_hostname_csr($certsdir,$sslkeypass,$replicatecsr,$replicatesubj);
+ &mail_csr('hostname',$lonCluster,$perlvar{'lonHostID'},$desiredhostname,$certsdir,$connectcsr,$replicatecsr,$perlvarstatic);
+ print "\nRetrieving status information for SSL key and certificates ...\n\n";
+ ($certinfo,$lonkeystatus,$lonhostcertstatus,$lonhostnamecertstatus,$sslref) =
+ &get_cert_status($perlvar{'lonHostID'},$perlvarstatic);
+ if (ref($sslref) eq 'HASH') {
+ %sslstatus = %{$sslref};
+ }
+ } elsif ($choice2 eq '3') {
+ if (-e "$certsdir/$replicatecsr") {
+ &mail_csr('hostname',$lonCluster,$perlvar{'lonHostID'},$desiredhostname,$certsdir,$connectcsr,$replicatecsr,$perlvarstatic);
+ }
+ }
+ } elsif (($sslstatus{'hostname'} == 0) || ($sslstatus{'hostname'} == 4) || ($sslstatus{'hostname'} == 5)) {
+ my $sslkeypass;
+ if ($sslstatus{'key'} == 1) {
+ 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) make no change
+ENTER NEW VALUE
+END
+ my $choice2=<>;
+ chomp($choice2);
+ if ($choice2 eq '1') {
+ $sslkeypass = &get_new_sslkeypass();
+ &make_key($certsdir,$privkey,$sslkeypass);
+ } elsif ($choice2 eq '2') {
+ $sslkeypass = &get_password('Enter existing password for SSL key');
+ &encrypt_key($certsdir,$privkey,$sslkeypass);
+ }
+ } else {
+ print(<<END);
+17) SSL Certificate for Content Replication: $lonhostnamecertstatus
+END
+ $sslkeypass = &get_new_sslkeypass();
+ }
+ &ssl_info();
+ my $country = &get_country($desiredhostname);
+ my $state = &get_state();
+ my $city = &get_city();
+ my $replicatesubj = "/C=$country/ST=$state/O=$domainDescription/L=$city/CN=internal-$desiredhostname/OU=LONCAPA/emailAddress=$adminmail";
+ &make_hostname_csr($certsdir,$sslkeypass,$replicatecsr,$replicatesubj);
+ &mail_csr('hostname',$lonCluster,$perlvar{'lonHostID'},$desiredhostname,$certsdir,$connectcsr,$replicatecsr,$perlvarstatic);
+ print "\nRetrieving status information for SSL key and certificates ...\n\n";
+ ($certinfo,$lonkeystatus,$lonhostcertstatus,$lonhostnamecertstatus,$sslref) =
+ &get_cert_status($perlvar{'lonHostID'},$perlvarstatic);
+ if (ref($sslref) eq 'HASH') {
+ %sslstatus = %{$sslref};
+ }
+ }
} elsif (($choice==18) && (!@error)) {
$flag=1;
} else {
@@ -1835,7 +2104,7 @@
if ($value eq '') {
$line = '#'.$line;
}
- print(OUT <<END) unless $perlvarstatic{$key};
+ print(OUT <<END) unless ($perlvarstatic->{$key});
$line
END
}
More information about the LON-CAPA-cvs
mailing list