App-Acmeman

 view release on metacpan or  search on metacpan

lib/App/Acmeman/Source/Apache.pm  view on Meta::CPAN

    }
    return 1;	
}

sub server_root {
    my $self = shift;
    if (my $v = shift) {
	croak "too many arguments" if $@;
	$self->{_server_root} = $v;
    }
    return $self->{_server_root} || $self->layout->apache->server_root;
}

sub mkpath {
    my ($self, $dir) = @_;
    my @created = make_path("$dir", { error => \my $err } );
    if (@$err) {
	for my $diag (@$err) {
	    my ($file, $message) = %$diag;
	    if ($file eq '') {
		error($message);
	    } else {
		error("mkdir $file: $message");
	    }
	}
	return 0;
    }
    return 1;
}

sub setup {
    my ($self, %args) = @_;
    my $filename = $self->layout->incdir() . "/httpd-letsencrypt.conf";
    if (-e $filename) {
	if ($args{force}) {
	    error("the file \"$filename\" already exists",
	 	  prefix => 'warning');
	} else {
	    error("the file \"$filename\" already exists");
	    error("use --force to continue");
	    return 0;
	}
    }
    my $www_root = $self->get(qw(core rootdir));
    debug(2, "writing $filename");
    unless ($args{dry_run}) {
	my $challenge_dir = "$www_root/.well-known/acme-challenge";
	my $acme_dir = $App::Acmeman::acme_dir;

	foreach my $dir ($self->layout->incdir(), $challenge_dir, $acme_dir) {
	    unless ($self->mkpath($dir)) {
		return 0;
	    }
	}

	$self->layout->pre_setup;

	open(my $fd, '>', $filename)
	    or croak "can't open \"$filename\" for writing: $!";
	print $fd <<EOT;
<Macro LetsEncryptChallenge>
    Alias /.well-known/acme-challenge $challenge_dir
    <Directory $challenge_dir>
        Options None
        Require all granted
    </Directory>
    <IfModule mod_rewrite.c>
        RewriteEngine On
	RewriteRule /.well-known/acme-challenge - [L]
    </IfModule>
</Macro>

<Macro LetsEncryptReference \$domain>
    Use LetsEncryptChallenge
    Alias /.dummy/\$domain /dev/null
</Macro>

<Macro LetsEncryptSSL \$domain>
    SSLEngine on
    SSLProtocol all -SSLv2 -SSLv3
    SSLHonorCipherOrder on
    SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:E...
    SSLCertificateFile $acme_dir/\$domain/cert.pem
    SSLCertificateKeyFile $acme_dir/\$domain/privkey.pem
    SSLCACertificateFile $acme_dir/$App::Acmeman::letsencrypt_root_cert_basename
</Macro>

<Macro LetsEncryptServer \$domain>
    ServerName \$domain
    Use LetsEncryptSSL \$domain
</Macro>

EOT
;
	close $fd;
	error("created file \"$filename\"", prefix => 'note');
	
	$self->layout->post_setup($filename);
    }

    my $pfx = "please,";
    unless ($self->is_letsencryptssl_defined) {
	error("please, make sure your Apache configuration includes this file",
	      prefix => 'note');
	$pfx = "and";
    }
    
    unless ($self->layout->apache_modules('macro')) {
	error("$pfx enable mod_macro",
	      prefix => 'note');
    }
    return 1;
}

# Check if LetsEncryptSSL macro is defined
sub is_letsencryptssl_defined {
    my ($self) = @_;
    my $app = new Apache::Config::Preproc(
	$self->layout->config_file,
	-expand => [ 'compact',
		     { 'include' => [ server_root => $self->server_root ] },
		     { 'macro' => [
			   'keep' => [ qw(LetsEncryptChallenge
                                          LetsEncryptReference
                                          LetsEncryptSSL)
			   ]
		       ]
		     }
	]);
    if ($app) {
	return grep { $_->value =~ m{^(?i)letsencryptssl\s+} }
	   $app->section(-name => "macro");
    } else {
	debug(1, $Apache::Admin::Config::ERROR);
	return undef
    }
}

1;



( run in 0.710 second using v1.01-cache-2.11-cpan-99c4e6809bf )