Re-factored SSL cert creation code

This commit is contained in:
Jamie Cameron
2007-12-11 01:13:17 +00:00
parent 4872a209db
commit 70d9fc84fb
4 changed files with 120 additions and 85 deletions

View File

@@ -120,36 +120,8 @@ print &ui_table_start($text{'ssl_header1'}, undef, 2);
$host = $ENV{'HTTP_HOST'};
$host =~ s/:.*//;
print &ui_table_row($text{'ssl_cn'},
&ui_opt_textbox("commonName", $host, 30,
$text{'ssl_all'}));
print &ui_table_row($text{'ca_email'},
&ui_textbox("emailAddress", $d->{'emailto'}, 30));
print &ui_table_row($text{'ca_ou'},
&ui_textbox("organizationalUnitName", undef, 30));
$o = "Webmin Webserver on ".&get_system_hostname();
print &ui_table_row($text{'ca_o'},
&ui_textbox("organizationName", $o, 30));
print &ui_table_row($text{'ca_city'},
&ui_textbox("cityName", undef, 30));
print &ui_table_row($text{'ca_sp'},
&ui_textbox("stateOrProvinceName", undef, 15));
print &ui_table_row($text{'ca_c'},
&ui_textbox("countryName", undef, 2));
print &ui_table_row($text{'ssl_size'},
&ui_opt_textbox("size", undef, 6,
"$text{'default'} ($default_key_size)").
" ".$text{'ssl_bits'});
print &ui_table_row($text{'ssl_days'},
&ui_textbox("days", 1825, 8));
print &show_ssl_key_form($host, undef,
"Webmin Webserver on ".&get_system_hostname());
print &ui_table_row($text{'ssl_newfile'},
&ui_textbox("newfile", "$config_directory/miniserv.pem", 40));

View File

@@ -364,6 +364,7 @@ newkey_ecat=An error occurred writing to the new key file :
newkey_ok=Successfully generated the following SSL key.
newkey_esize=Missing or invalid key size
newkey_edays=Missing or invalid number of days before expiry
newkey_ecountry=Country code must be two letters
startpage_title=Index Page Options
startpage_intro2=This page allows you to control the appearance of the main Webmin menu. Some options may only be effective when using the default theme.

View File

@@ -4,65 +4,17 @@
require './webmin-lib.pl';
&ReadParse();
# Validate inputs
&error_setup($text{'newkey_err'});
$in{'commonName_def'} || $in{'commonName'} =~ /^[A-Za-z0-9\.\-\*]+$/ ||
&error($text{'newkey_ecn'});
$in{'newfile'} || &error($text{'newkey_efile'});
$in{'size_def'} || $in{'size'} =~ /^\d+$/ || &error($text{'newkey_esize'});
$in{'days'} =~ /^\d+$/ || &error($text{'newkey_edays'});
# Validate inputs and create the key
$err = &parse_ssl_key_form(\%in, $in{'newfile'});
&error($err) if ($err);
# Tell the user
&ui_print_header(undef, $text{'newkey_title'}, "");
%aclconfig = &foreign_config('acl');
&foreign_require("acl", "acl-lib.pl");
if (!($cmd = &acl::get_ssleay())) {
print "<p>",&text('newkey_ecmd', "<tt>$aclconfig{'ssleay'}</tt>",
"$gconfig{'webprefix'}/config.cgi?acl"),"<p>\n";
&ui_print_footer("", $text{'index_return'});
exit;
}
# Create key file
$ctemp = &transname();
$ktemp = &transname();
$outtemp = &transname();
$size = $in{'size_def'} ? $default_key_size : $in{'size'};
open(CA, "| $cmd req -newkey rsa:$size -x509 -nodes -out $ctemp -keyout $ktemp -days $in{'days'} >$outtemp 2>&1");
print CA ($in{'countryName'} || "."),"\n";
print CA ($in{'stateOrProvinceName'} || "."),"\n";
print CA ($in{'cityName'} || "."),"\n";
print CA ($in{'organizationName'} || "."),"\n";
print CA ($in{'organizationalUnitName'} || "."),"\n";
print CA ($in{'commonName_def'} ? "*" : $in{'commonName'}),"\n";
print CA ($in{'emailAddress'} || "."),"\n";
close(CA);
$rv = $?;
$out = `cat $outtemp`;
unlink($outtemp);
if (!-r $ctemp || !-r $ktemp || $?) {
print "<p>$text{'newkey_essl'}<br>\n";
print "<pre>$out</pre>\n";
&ui_print_footer("", $text{'index_return'});
exit;
}
&lock_file($in{'newfile'});
$catout = `cat $ctemp $ktemp 2>&1 >'$in{'newfile'}'`;
unlink($ctemp);
unlink($ktemp);
if ($catout || $?) {
print "<p>$text{'newkey_ecat'}<br>\n";
print "<pre>$catout</pre>\n";
&ui_print_footer("", $text{'index_return'});
exit;
}
chmod(0600, $in{'newfile'});
&unlock_file($in{'newfile'});
print "<p>$text{'newkey_ok'}<br>\n";
$key = `cat '$in{'newfile'}'`;
print "<pre>$key</pre>";
$key = &read_file_contents($in{'newfile'});
print "<pre>".&html_escape($key)."</pre>";
&ui_print_footer("", $text{'index_return'});
# Configure webmin to use the new file

View File

@@ -1239,4 +1239,114 @@ close(BLOCKED);
return @rv;
}
# show_ssl_key_form([defhost], [defemail], [deforg])
# Returns HTML for inputs to generate a new self-signed cert
sub show_ssl_key_form
{
local ($defhost, $defemail, $deforg) = @_;
local $rv;
$rv .= &ui_table_row($text{'ssl_cn'},
&ui_opt_textbox("commonName", $defhost, 30,
$text{'ssl_all'}));
$rv .= &ui_table_row($text{'ca_email'},
&ui_textbox("emailAddress", $defemail, 30));
$rv .= &ui_table_row($text{'ca_ou'},
&ui_textbox("organizationalUnitName", undef, 30));
$rv .= &ui_table_row($text{'ca_o'},
&ui_textbox("organizationName", $deforg, 30));
$rv .= &ui_table_row($text{'ca_city'},
&ui_textbox("cityName", undef, 30));
$rv .= &ui_table_row($text{'ca_sp'},
&ui_textbox("stateOrProvinceName", undef, 15));
$rv .= &ui_table_row($text{'ca_c'},
&ui_textbox("countryName", undef, 2));
$rv .= &ui_table_row($text{'ssl_size'},
&ui_opt_textbox("size", undef, 6,
"$text{'default'} ($default_key_size)").
" ".$text{'ssl_bits'});
$rv .= &ui_table_row($text{'ssl_days'},
&ui_textbox("days", 1825, 8));
return $rv;
}
# parse_ssl_key_form(&in, keyfile, [certfile])
# Parses the key generation form, and creates new key and cert files.
# Returns undef on success or an error message on failure.
sub parse_ssl_key_form
{
local ($in, $keyfile, $certfile) = @_;
local %in = %$in;
# Validate inputs
$in{'commonName_def'} || $in{'commonName'} =~ /^[A-Za-z0-9\.\-\*]+$/ ||
return $text{'newkey_ecn'};
$in{'newfile'} || return $text{'newkey_efile'};
$in{'size_def'} || $in{'size'} =~ /^\d+$/ || return $text{'newkey_esize'};
$in{'days'} =~ /^\d+$/ || return $text{'newkey_edays'};
$in{'countryName'} =~ /^\S\S$/ || return $text{'newkey_ecountry'};
# Work out SSL command
local %aclconfig = &foreign_config('acl');
&foreign_require("acl", "acl-lib.pl");
local $cmd = &acl::get_ssleay();
if (!$cmd) {
return &text('newkey_ecmd', "<tt>$aclconfig{'ssleay'}</tt>",
"$gconfig{'webprefix'}/config.cgi?acl");
}
# Run openssl and feed it key data
local $ctemp = &transname();
local $ktemp = &transname();
local $outtemp = &transname();
local $size = $in{'size_def'} ? $default_key_size : quotemeta($in{'size'});
open(CA, "| $cmd req -newkey rsa:$size -x509 -nodes -out $ctemp -keyout $ktemp -days ".quotemeta($in{'days'})." >$outtemp 2>&1");
print CA ($in{'countryName'} || "."),"\n";
print CA ($in{'stateOrProvinceName'} || "."),"\n";
print CA ($in{'cityName'} || "."),"\n";
print CA ($in{'organizationName'} || "."),"\n";
print CA ($in{'organizationalUnitName'} || "."),"\n";
print CA ($in{'commonName_def'} ? "*" : $in{'commonName'}),"\n";
print CA ($in{'emailAddress'} || "."),"\n";
close(CA);
local $rv = $?;
local $out = &read_file_contents($outtemp);
unlink($outtemp);
if (!-r $ctemp || !-r $ktemp || $?) {
return $text{'newkey_essl'}."<br>"."<pre>".&html_escape($out)."</pre>";
}
# Write to the final files
local $certout = &read_file_contents($ctemp);
local $keyout = &read_file_contents($ktemp);
unlink($ctemp, $ktemp);
&open_lock_tempfile(KEYFILE, ">$keyfile");
&print_tempfile(KEYFILE, $keyout);
if ($certfile) {
# Separate files
&open_lock_tempfile(CERTFILE, ">$certfile");
&print_tempfile(CERTFILE, $certout);
&close_tempfile(CERTFILE);
&set_ownership_permissions(undef, undef, 0600, $certfile);
}
else {
# Both go in the same file
&print_tempfile(KEYFILE, $certout);
}
&close_tempfile(KEYFILE);
&set_ownership_permissions(undef, undef, 0600, $keyfile);
return undef;
}
1;