-#! /usr/bin/perl
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-# Copyright (C) 2016 - 2017 Raphaël Gertz <acme@rapsys.eu>
-
-# Best practice
-use strict;
-use warnings;
-
-# Fix use of acl
-use filetest qw(access);
-
-# Load dependancies
-use File::stat qw(stat);
-use File::Slurp qw(read_file);
-use JSON qw(decode_json);
-use Acme;
-
-# Load POSIX
-use POSIX qw(EXIT_SUCCESS EXIT_FAILURE);
-
-# Init debug
-my $debug = 0;
-
-# Init config
-my $config = undef;
-
-# Init config file name
-my $configFilename = '/etc/acme/config';
-
-# Init domains
-my @domains = ();
-
-# Strip and enable debug
-@ARGV = map { if ($_ eq '-d') { $debug = 1; (); } else { $_; } } @ARGV;
-
-# Strip and enable debug
-for (my $i = 0; $i <= $#ARGV; $i++) {
- # Match redhat types
- if ($ARGV[$i] =~ /^(?:(\-c|\-\-config)(?:=(.+))?)$/) {
- if (defined($2) && -f $2) {
- $configFilename = $2;
- splice(@ARGV, $i, 1);
- $i--;
- # Extract next parameter
- } elsif(defined($ARGV[$i+1]) && $ARGV[$i+1] =~ /^(.+)$/ && -f $1) {
- $configFilename = $1;
- splice(@ARGV, $i, 2);
- $i--;
- # Set default
- } else {
- print 'Config parameter without valid file name'."\n";
- exit EXIT_FAILURE;
- }
- }
-}
-
-# Load config
-unless (
- #XXX: use eval to workaround a fatal in decode_json
- eval {
- # Check file
- (-f $configFilename) &&
- # Read it
- ($config = read_file($configFilename)) &&
- # Decode it
- ($config = decode_json($config)) &&
- # Check hash validity
- defined($config->{certificates}) &&
- # Check not empty
- scalar($config->{certificates}) &&
- # Check hash validity
- defined($config->{thumbprint}) &&
- # Check certificates array
- ! scalar map {unless(defined($_->{cert}) && defined($_->{key}) && defined($_->{mail}) && defined($_->{domain}) && defined($_->{domains})) {1;} else {();}} @{$config->{certificates}}
- }
-) {
- print 'Config file '.$configFilename.' is not readable or invalid'."\n";
- exit EXIT_FAILURE;
-}
-
-# Deal with specified domains
-if (scalar(@ARGV) > 0) {
- # Check that domains are present in config
- foreach my $domain (@ARGV) {
- my $found = undef;
- foreach my $certificate (@{$config->{certificates}}) {
- if ($certificate->{domain} eq $domain) {
- push(@domains, $certificate);
- $found = 1;
- }
- }
- unless($found) {
- print 'Domain '.$domain.' not found in config file '.$configFilename."\n";
- exit EXIT_FAILURE;
- }
- }
-# Without it
-} else {
- # Populate domains array with available ones
- foreach my $certificate (@{$config->{certificates}}) {
- push(@domains, $certificate);
- }
-}
-
-# Show usage
-if (scalar(@domains) < 1) {
- print "Usage: $0 [-(c|-config)[=/etc/acme/config]] [example.com] [...]\n";
- exit EXIT_FAILURE;
-}
-
-# Deal with each domain
-foreach my $domain (@domains) {
- # Skip certificate without 60 days
- if (-f $domain->{cert} && stat($domain->{cert})->mtime >= (time() - 60*24*3600)) {
- next;
- }
-
- # Create new object
- my $acme = Acme->new($debug, $domain, {thumbprint => $config->{thumbprint}, pending => $config->{pending}, term => $config->{term}});
-
- # Prepare environement
- $acme->prepare();
-
- # Generate required keys
- $acme->genKeys();
-
- # Generate csr
- $acme->genCsr();
-
- # Directory
- $acme->directory();
-
- # Register
- $acme->register();
-
- # Authorize
- $acme->authorize();
-
- # Issue
- $acme->issue();
-}
-
-# Exit with success
-exit EXIT_SUCCESS;