#!/usr/local/bin/perl
# edit_ssl.cgi
-# Configure whether Usermin uses SSL or not
+# Webserver SSL form
require './usermin-lib.pl';
-$access{'ssl'} || &error($text{'acl_ecannot'});
&ui_print_header(undef, $text{'ssl_title'}, "");
+&ReadParse();
&get_usermin_miniserv_config(\%miniserv);
-$@ = undef;
-eval "use Net::SSLeay";
-if ($@) {
- print &text('ssl_essl', "http://www.webmin.com/ssl.html"),"\n";
- }
-else {
- print $text{'ssl_desc1'},"<p>\n";
- print $text{'ssl_desc2'},"<br>\n";
-
- print "<form action=change_ssl.cgi>\n";
- print "<table border>\n";
- print "<tr $tb> <td><b>$text{'ssl_header'}</b></td> </tr>\n";
- print "<tr $cb> <td><table>\n";
-
- print "<tr> <td><b>$text{'ssl_on'}</b></td>\n";
- printf "<td><input type=radio name=ssl value=1 %s> %s\n",
- $miniserv{'ssl'} ? "checked" : "", $text{'yes'};
- printf "<input type=radio name=ssl value=0 %s> %s</td> </tr>\n",
- $miniserv{'ssl'} ? "" : "checked", $text{'no'};
-
- print "<tr> <td><b>$text{'ssl_key'}</b></td>\n";
- printf "<td><input name=key size=40 value='%s'> %s</td> </tr>\n",
- $miniserv{'keyfile'}, &file_chooser_button("key");
-
- print "<tr> <td valign=top><b>$text{'ssl_cert'}</b></td>\n";
- printf "<td><input type=radio name=cert_def value=1 %s> %s<br>\n",
- $miniserv{'certfile'} ? "" : "checked",
- $text{'ssl_cert_def'};
- printf "<input type=radio name=cert_def value=0 %s> %s\n",
- $miniserv{'certfile'} ? "checked" : "",
- $text{'ssl_cert_oth'};
- printf "<input name=cert size=40 value='%s'> %s</td> </tr>\n",
- $miniserv{'certfile'}, &file_chooser_button("cert");
-
- print "<tr> <td><b>$text{'ssl_redirect'}</b></td>\n";
- printf "<td><input type=radio name=ssl_redirect value=1 %s> %s\n",
- $miniserv{'ssl_redirect'} ? "checked" : "", $text{'yes'};
- printf "<input type=radio name=ssl_redirect value=0 %s> %s</td></tr>\n",
- $miniserv{'ssl_redirect'} ? "" : "checked", $text{'no'};
-
- print "<tr> <td><b>$text{'ssl_version'}</b></td>\n";
- print "<td>",&ui_opt_textbox("version", $miniserv{'ssl_version'}, 4,
- $text{'ssl_auto'}),"</td> </tr>\n";
-
- print "<tr> <td><b>$text{'ssl_cipher_list'}</b></td>\n";
- print "<td>",&ui_opt_textbox("cipher_list",
- $miniserv{'ssl_cipher_list'}, 30,
- $text{'ssl_auto'})."</td> </tr>\n";
-
- print "<tr> <td valign=top><b>$text{'ssl_extracas'}</b></td>\n";
- print "<td><textarea name=extracas rows=3 cols=40>";
- foreach $e (split(/\s+/, $miniserv{'extracas'})) {
- print "$e\n";
- }
- print "</textarea></td> </tr>\n";
-
- print "</table></td></tr></table>\n";
- print "<input type=submit value=\"$text{'save'}\"></form>\n";
-
- print &ui_hr();
-
- # Table listing per-IP SSL certs
- print "$text{'ssl_ipkeys'}<p>\n";
- @ipkeys = &webmin::get_ipkeys(\%miniserv);
- if (@ipkeys) {
- print &ui_columns_start([ $text{'ssl_ips'},
- $text{'ssl_key'},
- $text{'ssl_cert'} ]);
- foreach $k (@ipkeys) {
- print &ui_columns_row([
- "<a href='edit_ipkey.cgi?idx=$k->{'index'}'>".
- join(", ", @{$k->{'ips'}})."</a>",
- "<tt>$k->{'key'}</tt>",
- $k->{'cert'} ? "<tt>$k->{'cert'}</tt>" : "<br>"
- ]);
- }
- print &ui_columns_end();
+# Show tabs
+@tabs = map { [ $_, $text{'ssl_tab'.$_}, "edit_ssl.cgi?mode=$_" ] }
+ ( "ssl", "current", "ips", "create", "upload" );
+print &ui_tabs_start(\@tabs, "mode", $in{'mode'} || $tabs[0]->[0], 1);
+
+# Basic SSL settings
+print &ui_tabs_start_tab("mode", "ssl");
+print $text{'ssl_desc1'},"<p>\n";
+print $text{'ssl_desc2'},"<p>\n";
+
+print &ui_form_start("change_ssl.cgi", "post");
+print &ui_table_start($text{'ssl_header'}, undef, 2);
+
+print &ui_table_row($text{'ssl_on'},
+ &ui_yesno_radio("ssl", $miniserv{'ssl'}));
+
+print &ui_table_row($text{'ssl_key'},
+ &ui_textbox("key", $miniserv{'keyfile'}, 40)." ".
+ &file_chooser_button("key"));
+
+print &ui_table_row($text{'ssl_cert'},
+ &ui_opt_textbox("cert", $miniserv{'certfile'}, 40,
+ $text{'ssl_cert_def'}."<br>",$text{'ssl_cert_oth'})." ".
+ &file_chooser_button("cert"));
+
+print &ui_table_row($text{'ssl_redirect'},
+ &ui_yesno_radio("ssl_redirect", $miniserv{'ssl_redirect'}));
+
+print &ui_table_row($text{'ssl_version'},
+ &ui_opt_textbox("version", $miniserv{'ssl_version'}, 4,
+ $text{'ssl_auto'}));
+
+$clist = $miniserv{'ssl_cipher_list'};
+$cmode = !$clist ? 1 :
+ $clist eq $webmin::strong_ssl_ciphers ? 2 : 0;
+print &ui_table_row($text{'ssl_cipher_list'},
+ &ui_radio("cipher_list_def", $cmode,
+ [ [ 1, $text{'ssl_auto'}."<br>" ],
+ [ 2, $text{'ssl_strong'}."<br>" ],
+ [ 0, $text{'ssl_clist'}." ".
+ &ui_textbox("cipher_list",
+ $cmode == 0 ? $clist : "", 30) ] ]));
+
+print &ui_table_row($text{'ssl_extracas'},
+ &ui_textarea("extracas", join("\n",split(/\s+/, $miniserv{'extracas'})),
+ 3, 60)." ".
+ &file_chooser_button("extracas", 0, undef, undef, 1));
+
+print &ui_table_end();
+print &ui_form_end([ [ "", $text{'save'} ] ]);
+print &ui_tabs_end_tab();
+
+# Page showing current cert
+print &ui_tabs_start_tab("mode", "current");
+print "$text{'ssl_current'}<p>\n";
+print &ui_table_start($text{'ssl_cheader'}, undef, 4);
+$info = &webmin::cert_info($miniserv{'certfile'} || $miniserv{'keyfile'});
+foreach $i ('cn', 'o', 'email', 'issuer_cn', 'issuer_o', 'issuer_email',
+ 'notafter', 'type') {
+ if ($info->{$i}) {
+ print &ui_table_row($text{'ca_'.$i}, $info->{$i});
}
- else {
- print "<b>$text{'ssl_ipkeynone'}</b><p>\n";
- }
- print "<a href='edit_ipkey.cgi?new=1'>$text{'ssl_addipkey'}</a><p>\n";
-
- # SSL key generation form
- print &ui_hr();
- print "$text{'ssl_newkey'}\n";
- local $curkey = `cat $miniserv{'keyfile'} 2>/dev/null`;
- local $origkey = `cat $miniserv{'root'}/miniserv.pem 2>/dev/null`;
- if ($curkey eq $origkey) {
- # System is using the original (insecure) Usermin key!
- print "<b>$text{'ssl_hole'}</b>\n";
+ }
+@clinks = (
+ "<a href='download_cert.cgi/cert.pem'>".
+ "$text{'ssl_pem'}</a>",
+ "<a href='download_cert.cgi/cert.p12'>".
+ "$text{'ssl_pkcs12'}</a>"
+ );
+print &ui_table_row($text{'ssl_download'}, &ui_links_row(\@clinks));
+print &ui_table_end();
+print &ui_tabs_end_tab();
+
+# Table listing per-IP SSL certs
+print &ui_tabs_start_tab("mode", "ips");
+print "$text{'ssl_ipkeys'}<p>\n";
+@ipkeys = &webmin::get_ipkeys(\%miniserv);
+if (@ipkeys) {
+ print &ui_columns_start([ $text{'ssl_ips'}, $text{'ssl_key'},
+ $text{'ssl_cert'} ]);
+ foreach $k (@ipkeys) {
+ print &ui_columns_row([
+ "<a href='edit_ipkey.cgi?idx=$k->{'index'}'>".
+ join(", ", @{$k->{'ips'}})."</a>",
+ "<tt>$k->{'key'}</tt>",
+ $k->{'cert'} ? "<tt>$k->{'cert'}</tt>"
+ : $text{'ssl_cert_def'},
+ ]);
}
- print "<p>\n";
-
- print "<form action=newkey.cgi>\n";
- print "<table border>\n";
- print "<tr $tb> <td><b>$text{'ssl_header1'}</b></td> </tr>\n";
- print "<tr $cb> <td><table>\n";
- print "<tr> <td><b>$text{'ssl_cn'}</b></td>\n";
- print "<td><input type=radio name=commonName_def value=1 checked> ",
- "$text{'ssl_all'}\n";
- print "<input type=radio name=commonName_def value=0>\n";
- $host = $ENV{'HTTP_HOST'};
- $host =~ s/:.*//;
- print "<input name=commonName size=30 value='$host'></td> </tr>\n";
-
- print "<tr> <td><b>$text{'ca_email'}</b></td>\n";
- printf "<td><input name=emailAddress size=30 value='%s'></td> </tr>\n",
- "usermin\@".&get_system_hostname();
-
- print "<tr> <td><b>$text{'ca_ou'}</b></td>\n";
- print "<td><input name=organizationalUnitName size=30></td> </tr>\n";
-
- $hostname = &get_system_hostname();
- print "<tr> <td><b>$text{'ca_o'}</b></td>\n";
- print "<td><input name=organizationName size=30 ",
- "value='Usermin Webserver on $hostname'></td> </tr>\n";
-
- print "<tr> <td><b>$text{'ca_city'}</b></td>\n";
- print "<td><input name=cityName size=30></td> </tr>\n";
-
- print "<tr> <td><b>$text{'ca_sp'}</b></td>\n";
- print "<td><input name=stateOrProvinceName size=15></td> </tr>\n";
-
- print "<tr> <td><b>$text{'ca_c'}</b></td>\n";
- print "<td><input name=countryName size=2></td> </tr>\n";
-
- print "<tr> <td><b>$text{'ssl_size'}</b></td>\n";
- print "<td><input type=radio name=size_def value=1 checked> ",
- "$text{'default'} ($default_key_size)\n";
- print "<input type=radio name=size_def value=0> ",
- "$text{'ssl_custom'}\n";
- print "<input name=size size=6> $text{'ssl_bits'}</td> </tr>\n";
-
- print "<tr> <td><b>$text{'ssl_days'}</b></td>\n";
- print "<td><input name=days size=8 value='1825'></td> </tr>\n";
-
- print "<tr> <td><b>$text{'ssl_newfile'}</b></td>\n";
- printf "<td><input name=newfile size=40 value='%s'></td> </tr>\n",
- "$config{'usermin_dir'}/miniserv.pem";
-
- print "<tr> <td><b>$text{'ssl_usenew'}</b></td> <td>\n";
- print "<input type=radio name=usenew value=1 checked> $text{'yes'}\n";
- print "<input type=radio name=usenew value=0> $text{'no'}</td> </tr>\n";
-
- print "</table></td></tr></table>\n";
- print "<input type=submit value='$text{'ssl_create'}'></form>\n";
+ print &ui_columns_end();
}
+else {
+ print "<b>$text{'ssl_ipkeynone'}</b><p>\n";
+ }
+print "<a href='edit_ipkey.cgi?new=1'>$text{'ssl_addipkey'}</a><p>\n";
+print &ui_tabs_end_tab();
+
+# SSL key generation form
+print &ui_tabs_start_tab("mode", "create");
+print "$text{'ssl_newkey'}<p>\n";
+my $curkey = &read_file_contents($miniserv{'keyfile'});
+my $origkey = &read_file_contents("$root_directory/miniserv.pem");
+if ($curkey eq $origkey) {
+ # System is using the original (insecure) Webmin key!
+ print "<b>$text{'ssl_hole'}</b><p>\n";
+ }
+
+print &ui_form_start("newkey.cgi");
+print &ui_table_start($text{'ssl_header1'}, undef, 2);
+
+$host = $ENV{'HTTP_HOST'};
+$host =~ s/:.*//;
+print &webmin::show_ssl_key_form($host, undef,
+ "Usermin Webserver on ".&get_system_hostname());
+
+print &ui_table_row($text{'ssl_newfile'},
+ &ui_textbox("newfile", "$config{'usermin_dir'}/miniserv.pem", 40));
+
+print &ui_table_row($text{'ssl_usenew'},
+ &ui_yesno_radio("usenew", 1));
+
+print &ui_table_end();
+print &ui_form_end([ [ "", $text{'ssl_create'} ] ]);
+print &ui_tabs_end_tab();
+
+# SSL key upload form
+print &ui_tabs_start_tab("mode", "upload");
+print "$text{'ssl_savekey'}<p>\n";
+print &ui_form_start("savekey.cgi", "form-data");
+print &ui_table_start($text{'ssl_saveheader'}, undef, 2);
+
+print &ui_table_row($text{'ssl_privkey'},
+ &ui_textarea("key", undef, 7, 70)."<br>\n".
+ "<b>$text{'ssl_upload'}</b>\n".
+ &ui_upload("keyfile"));
+
+print &ui_table_row($text{'ssl_privcert'},
+ &ui_radio("cert_def", 1,
+ [ [ 1, $text{'ssl_same'} ],
+ [ 0, $text{'ssl_below'} ] ])."<br>\n".
+ &ui_textarea("cert", undef, 7, 70)."<br>\n".
+ "<b>$text{'ssl_upload'}</b>\n".
+ &ui_upload("certfile"));
+
+print &ui_table_row($text{'ssl_privchain'},
+ &ui_radio("chain_def", 1,
+ [ [ 1, $miniserv{'extracas'} ? $text{'ssl_leavechain'}
+ : $text{'ssl_nochain'} ],
+ [ 0, $text{'ssl_below'} ] ])."<br>\n".
+ &ui_textarea("chain", undef, 7, 70)."<br>\n".
+ "<b>$text{'ssl_upload'}</b>\n".
+ &ui_upload("chainfile"));
+
+print &ui_table_end();
+print &ui_form_end([ [ "save", $text{'save'} ] ]);
+print &ui_tabs_end_tab();
+
+print &ui_tabs_end(1);
&ui_print_footer("", $text{'index_return'});
--- /dev/null
+#!/usr/local/bin/perl
+# Replace the existing Webmin SSL key
+
+require './usermin-lib.pl';
+&ReadParseMime();
+&error_setup($text{'savekey_err'});
+
+# Validate inputs
+$key = $in{'key'} || $in{'keyfile'};
+$key =~ s/\r//g;
+$key =~ /BEGIN RSA PRIVATE KEY/ &&
+ $key =~ /END RSA PRIVATE KEY/ || &error($text{'savekey_ekey'});
+if (!$in{'cert_def'}) {
+ # Make sure cert is valid
+ $cert = $in{'cert'} || $in{'certfile'};
+ $cert =~ s/\r//g;
+ $cert =~ /BEGIN CERTIFICATE/ &&
+ $cert =~ /END CERTIFICATE/ || &error($text{'savekey_ecert'});
+ }
+else {
+ # Make sure key contains cert
+ $key =~ /BEGIN CERTIFICATE/ &&
+ $key =~ /END CERTIFICATE/ || &error($text{'savekey_ecert2'});
+ }
+if (!$in{'chain_def'}) {
+ # Make sure chained cert is valid
+ $chain = $in{'chain'} || $in{'chainfile'};
+ $chain =~ s/\r//g;
+ $chain =~ /BEGIN CERTIFICATE/ &&
+ $chain =~ /END CERTIFICATE/ || &error($text{'savekey_echain'});
+ }
+
+# Save config and key file
+&lock_file($usermin_miniserv_config);
+&get_usermin_miniserv_config(\%miniserv);
+$miniserv{'keyfile'} ||= "$config_directory/miniserv.pem";
+&lock_file($miniserv{'keyfile'});
+&open_tempfile(KEY, ">$miniserv{'keyfile'}");
+&print_tempfile(KEY, $key);
+&close_tempfile(KEY);
+&unlock_file($miniserv{'keyfile'});
+if ($in{'cert_def'}) {
+ delete($miniserv{'certfile'});
+ }
+else {
+ $miniserv{'certfile'} ||= "$config_directory/miniserv.cert";
+ &lock_file($miniserv{'certfile'});
+ &open_tempfile(CERT, ">$miniserv{'certfile'}");
+ &print_tempfile(CERT, $cert);
+ &close_tempfile(CERT);
+ &unlock_file($miniserv{'certfile'});
+ }
+if (!$in{'chain_def'}) {
+ $miniserv{'extracas'} = "$config_directory/miniserv.chain"
+ if (!$miniserv{'extracas'} || $miniserv{'extracas'} =~ /\s/);
+ &lock_file($miniserv{'extracas'});
+ &open_tempfile(CERT, ">$miniserv{'extracas'}");
+ &print_tempfile(CERT, $chain);
+ &close_tempfile(CERT);
+ &unlock_file($miniserv{'extracas'});
+ }
+&put_usermin_miniserv_config(\%miniserv);
+&unlock_file($usermin_miniserv_config);
+
+# Tell the user
+&ui_print_header(undef, $text{'savekey_title'}, "");
+
+if ($miniserv{'certfile'}) {
+ print &text('savekey_done2', "<tt>$miniserv{'keyfile'}</tt>",
+ "<tt>$miniserv{'certfile'}</tt>"),"<p>\n";
+ }
+else {
+ print &text('savekey_done', "<tt>$miniserv{'keyfile'}</tt>"),"<p>\n";
+ }
+if (!$in{'chain_def'}) {
+ print &text('savekey_done3', "<tt>$miniserv{'extracas'}</tt>"),"<p>\n";
+ }
+
+&ui_print_footer("", $text{'index_return'});
+
+&webmin_log("savekey");
+&restart_usermin_miniserv(1);