diff --git a/webmin/edit_ssl.cgi b/webmin/edit_ssl.cgi index ed0ae4a81..df573c3c9 100755 --- a/webmin/edit_ssl.cgi +++ b/webmin/edit_ssl.cgi @@ -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)); diff --git a/webmin/lang/en b/webmin/lang/en index d00475434..4daceaf5f 100644 --- a/webmin/lang/en +++ b/webmin/lang/en @@ -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. diff --git a/webmin/newkey.cgi b/webmin/newkey.cgi index 3d38e93a0..65d7b50de 100755 --- a/webmin/newkey.cgi +++ b/webmin/newkey.cgi @@ -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 "

",&text('newkey_ecmd', "$aclconfig{'ssleay'}", - "$gconfig{'webprefix'}/config.cgi?acl"),"

\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 "

$text{'newkey_essl'}
\n"; - print "

$out
\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 "

$text{'newkey_ecat'}
\n"; - print "

$catout
\n"; - &ui_print_footer("", $text{'index_return'}); - exit; - } -chmod(0600, $in{'newfile'}); -&unlock_file($in{'newfile'}); - print "

$text{'newkey_ok'}
\n"; -$key = `cat '$in{'newfile'}'`; -print "

$key
"; +$key = &read_file_contents($in{'newfile'}); +print "
".&html_escape($key)."
"; &ui_print_footer("", $text{'index_return'}); # Configure webmin to use the new file diff --git a/webmin/webmin-lib.pl b/webmin/webmin-lib.pl index 95128ab47..0bedca54c 100644 --- a/webmin/webmin-lib.pl +++ b/webmin/webmin-lib.pl @@ -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', "$aclconfig{'ssleay'}", + "$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'}."
"."
".&html_escape($out)."
"; + } + +# 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;