summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjake <jake@jakes-mail.top>2022-09-22 17:48:50 -0400
committerjake <jake@jakes-mail.top>2022-09-22 17:48:50 -0400
commit1aefd926555beac5d7618c2375727df0c4470504 (patch)
tree295d53c7c21d544ed69bd06ed8541e2ca5e4ea18
parent9aa5c9037d7e2dddc2ab46906bd34a23b0f7cd5b (diff)
Add server_alias config option.HEADmaster
Add map_server_alias. Modifed auto_cert to generate certs for the alias. Changed some logic for detecting server_alias'. Update the sample config file.
-rw-r--r--TO_FIX.md5
-rw-r--r--config.toml.sample4
-rwxr-xr-xgmi.pl77
3 files changed, 76 insertions, 10 deletions
diff --git a/TO_FIX.md b/TO_FIX.md
index 611c3c9..a2942eb 100644
--- a/TO_FIX.md
+++ b/TO_FIX.md
@@ -25,3 +25,8 @@ reduce complexity in cert_req()
permission denied when the file is readable (MAC permissions)
use GetOpt::Long in a reasonable manner
+
+map_server_alias() perhaps should not exist.
+In general, I am unsatisfied with the program keeping the configuration file in memory and constantly referring to it. map_server_alias() literally just copies it's vhost's config and keeps it in the config hash.
+
+reduce complexity in listen_config()
diff --git a/config.toml.sample b/config.toml.sample
index c1962c7..a668491 100644
--- a/config.toml.sample
+++ b/config.toml.sample
@@ -80,6 +80,10 @@ assume_index = true
# A more realistic example
#['example.com']
+# Listen to more than just 'example.com' with server_alias. No need two vhost configurations.
+# server_alias can just be a single string, e.g. "server_alias='www.example.com'". An array allows
+# for more than one alias. If auto_cert is true, then *ON CREATION OF THE CERT* the server_alias's will be added to it.
+#server_alias=['www.example.com', 'example.org']
# bind can be set to a string or a list or 'no' which will not be accessible via IP address.
#bind = ['172.16.0.53', '10.43.14.32']
#ports = [10000,10001,10002]
diff --git a/gmi.pl b/gmi.pl
index d3237c4..2029cc3 100755
--- a/gmi.pl
+++ b/gmi.pl
@@ -7,7 +7,7 @@ use warnings;
use 5.010;
#use diagnostics;
-our $VERSION = 'v0.19.0';
+our $VERSION = 'v0.20.0';
# Modules
use IO::Socket::SSL; # CPAN
@@ -68,7 +68,7 @@ const our @VALID_DEFAULT_SETTINGS =>
unix redirection redirect gone/;
const our @VALID_VHOST_SETTINGS =>
qw/auto_cert assume_index dir_listing root cert key default_mime bind ports
- unix redirection redirect cert_req gone/;
+ unix redirection redirect cert_req gone server_alias/;
my $config_path = './config.toml';
if ($ARGV[0]) {
@@ -96,9 +96,12 @@ my @srv = ip_config($listen_config);
my %ssl_config = ssl_config($config);
ssl_vhost_cert_key(\%ssl_config);
+### %ssl_config
my $fork_toggled = fork_toggle($config);
+map_server_alias($config);
+
# let the user know if an invalid option was used
check_config_keys($config);
@@ -142,6 +145,7 @@ while (my @ready = $sel->can_read) {
my $fh = shift @ready;
$cl = $fh->accept;
get_fh_data($fh, $cl, \%data);
+ ### %data
maybe_fork() and next;
@@ -165,6 +169,7 @@ while (my @ready = $sel->can_read) {
speak($cl, 'proxy_req_refused');
goto CLOSE;
}
+ ### %data
my $url;
my $path;
@@ -267,7 +272,7 @@ sub respond_to_client {
if (not $data{cl_path_translated} = get_request_in_vhost_root($vhost, $path)) {
goto FAILURE;
}
- ### $doc_loc
+ ## $doc_loc
# checking if the path already has .gone for 'some reason'
if (substr($data{cl_path_translated}, -5, 5) eq '.gone') { ## no critic (MagicNumbers)
@@ -380,6 +385,11 @@ sub gen_cert {
'not_before' => $not_before,
'not_after' => $not_after,
);
+ if (exists $config->{$hostname}{server_alias}) {
+ for my $alias (give_array($config->{$hostname}{server_alias})) {
+ push @{ $cert{subjectAltNames} }, ['DNS', $alias];
+ }
+ }
my ($cert, $key) = CERT_create(%cert);
my $old_umask = umask oct $UMASK_FOR_CERTS_KEYS;
@@ -737,6 +747,12 @@ sub ssl_vhost_cert_key {
my $cert_loc;
my $key_loc;
+ my @hosts;
+ push @hosts, $vhost;
+ if (exists $config->{$vhost}{server_alias}) {
+ push @hosts, give_array($config->{$vhost}{server_alias});
+ }
+
if (exists $config->{$vhost}{cert} and exists $config->{$vhost}{key}) {
$cert_loc = accurate_path($config->{$vhost}{cert}, $cert_key_dir);
if (! -e $cert_loc) {
@@ -771,8 +787,10 @@ sub ssl_vhost_cert_key {
}
if ($error_free) {
- $ssl_ref->{SSL_cert_file}{$vhost} = $cert_loc;
- $ssl_ref->{SSL_key_file}{$vhost} = $key_loc;
+ for my $host (@hosts) {
+ $ssl_ref->{SSL_cert_file}{$host} = $cert_loc;
+ $ssl_ref->{SSL_key_file}{$host} = $key_loc;
+ }
}
else {
serr("$vhost: will not listen for incoming requests.");
@@ -898,6 +916,7 @@ sub timeout_secs {
}
}
+## no critic (Complex)
sub listen_config {
my ($conf_ref, $ssl_ref, $ip_ref) = @_;
my %listen;
@@ -951,21 +970,45 @@ sub listen_config {
for my $port (give_array($ports)) {
for my $bind (give_array($binds)) {
push @{ $listen{$bind}{$port} }, $vhost;
+ if (exists $conf_ref->{$vhost}{server_alias}) {
+ push @{ $listen{$bind}{$port} }, give_array($conf_ref->{$vhost}{server_alias});
+ }
}
}
# check vhost unix socket otherwise check for default unix socket
- if (exists $conf_ref->{$vhost}{unix} and $conf_ref->{$vhost}{unix} ne 'no') {
- $listen{unix}{path}{$vhost} = $conf_ref->{$vhost}{unix};
- push @{ $listen{unix}{listen} }, $vhost;
+ if (exists $conf_ref->{$vhost}{unix}) {
+ if ($conf_ref->{$vhost}{unix} ne 'no') {
+ my @hosts;
+ push @hosts, $vhost;
+ if (exists $conf_ref->{$vhost}{server_alias}) {
+ for my $alias (give_array($conf_ref->{$vhost}{server_alias})) {
+ push @hosts, $alias;
+ }
+ }
+ for my $host (@hosts) {
+ $listen{unix}{path}{$host} = $conf_ref->{$vhost}{unix};
+ push @{ $listen{unix}{listen} }, $host;
+ }
+ }
}
elsif (exists $listen{unix}{path}{default}) {
- push @{ $listen{unix}{listen} }, $vhost;
+ my @hosts;
+ push @hosts, $vhost;
+ if (exists $conf_ref->{$vhost}{server_alias}) {
+ for my $alias (give_array($conf_ref->{$vhost}{server_alias})) {
+ push @hosts, $alias;
+ }
+ }
+ for my $host (@hosts) {
+ push @{ $listen{unix}{listen} }, $host;
+ }
}
}
# ## %listen
return \%listen;
}
+## use critic
sub give_array {
my ($ref) = @_;
@@ -1127,7 +1170,7 @@ sub verify_cert_callback {
#6. The depth of the certificate in the chain. Depth 0 is the leaf certificate.
## $pem
$data{cl_cert} = CERT_asHash(PEM_string2cert(Net::SSLeay::PEM_get_string_X509($_[4])));
- ### $cl_cert
+ ## $cl_cert
return 1;
}
## use critic
@@ -1297,3 +1340,17 @@ sub undef_data {
undef $data{cl_query_string};
return 1;
}
+
+sub map_server_alias {
+ my ($conf_ref) = @_;
+ for my $vhost ( keys %{ $conf_ref } ) {
+ next if ($vhost eq 'default');
+
+ if (exists $conf_ref->{$vhost}{server_alias}) {
+ for my $host ( give_array($conf_ref->{$vhost}{server_alias}) ) {
+ # not a deep copy, thankfully.
+ $conf_ref->{$host} = $conf_ref->{$vhost};
+ }
+ }
+ }
+}