#! /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 .
#
# Copyright (C) 2016 - 2017 Raphaƫl Gertz
# Best practice
use strict;
use warnings;
# Load required modules
use JSON;
use Tie::IxHash;
# Load POSIX
use POSIX qw(EXIT_SUCCESS EXIT_FAILURE);
# Init redhat
my @redhat = ();
# Init debian
my @debian = ();
# Init root
my %root = ();
tie(%root, 'Tie::IxHash', thumbprint => '/etc/acme/thumbprint', term => 'https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf', pending => '/tmp/acme.pending', certificates => []);
# Init prod
my $prod = 0;
# Strip and enable prod
@ARGV = map { if ($_ eq '-p') { $prod = 1; (); } else { $_; } } @ARGV;
# Strip and enable debug
for (my $i = 0; $i <= $#ARGV; $i++) {
# Match redhat types
if ($ARGV[$i] =~ /^(?:(\-r|\-\-redhat)(?:=([^-][a-zA-Z0-9_\.,-]+))?)$/) {
if (defined($2)) {
push(@redhat, [split(',', $2)]);
# Extract next parameter
} elsif(defined($ARGV[$i+1]) && $ARGV[$i+1] =~ /^([^-][a-zA-Z0-9_\.,-]+)$/) {
push(@redhat, [split(',', $1)]);
$i++;
# Set default
} else {
push(@redhat, ['www.example.com','example.com','...']);
}
# Match debian types
} elsif ($ARGV[$i] =~ /^(?:(\-d|\-\-debian)(?:=([^-][a-zA-Z0-9_\.,-]+))?)$/) {
if (defined($2)) {
push(@debian, [split(',', $2)]);
# Extract next parameter
} elsif(defined($ARGV[$i+1]) && $ARGV[$i+1] =~ /^([^-][a-zA-Z0-9_\.,-]+)$/) {
push(@debian, [split(',', $1)]);
$i++;
# Set default
} else {
push(@debian, ['www.example.com','example.com','...']);
}
# Match term
} elsif ($ARGV[$i] =~ /^(?:(\-t|\-\-term)(?:=(https:\/\/letsencrypt\.org\/documents\/[a-zA-Z0-9\._-]+\.pdf))?)$/) {
if (defined($2)) {
$root{term} = $2;
splice(@ARGV, $i, 1);
$i--;
# Extract next parameter
} elsif(defined($ARGV[$i+1]) && $ARGV[$i+1] =~ /^(https:\/\/letsencrypt\.org\/documents\/[a-zA-Z0-9\._-]+\.pdf)$/) {
$root{term} = $1;
splice(@ARGV, $i, 2);
$i--;
# Set default
} else {
print 'Term parameter without valid link'."\n";
exit EXIT_FAILURE;
}
}
}
# Show usage
if (scalar(@redhat) < 1 && scalar(@debian) < 1) {
print "Usage: $0 [(-d|--debian)[=example.com[,...]] [(-r|--redhat)[=example.com[,...]]] [(-t|--term)[=https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf]] [...] > /etc/acme/config\n";
exit EXIT_FAILURE;
}
# Append redhat style examples
for my $key (@redhat) {
my $domain = shift @{$key};
my @domains = $key;
tie(%{$root{certificates}[$#{$root{certificates}}+1]}, 'Tie::IxHash', (
# Public cert
#XXX: required
cert => '/etc/pki/tls/certs/'.$domain.'.pem',
# Private key
#XXX: required
key => '/etc/pki/tls/private/'.$domain.'.pem',
# Private account key
#XXX: required
account => '/etc/acme/account.pem',
# Mail address
#XXX: required
mail => 'webmaster@'.$domain,
# Root domain
#XXX: required
domain => $domain,
# Domain list
#XXX: required
domains => @domains,
# Production certificate
#XXX: optional
#XXX: set to 1 for production
prod => $prod
));
}
# Append debian style examples
for my $key (@debian) {
my $domain = shift @{$key};
my @domains = $key;
tie(%{$root{certificates}[$#{$root{certificates}}+1]}, 'Tie::IxHash', (
# Public cert
#XXX: required
cert => '/etc/ssl/certs/'.$domain.'.crt',
# Private key
#XXX: required
key => '/etc/ssl/private/'.$domain.'.key',
# Private account key
#XXX: required
account => '/etc/acme/account.pem',
# Mail address
#XXX: required
mail => 'webmaster@'.$domain,
# Root domain
#XXX: required
domain => $domain,
# Domain list
#XXX: required
domains => @domains,
# Production certificate
#XXX: optional
#XXX: set to 1 for production
prod => $prod
));
}
# Display configuration template
print to_json(\%root, {pretty => 1});
# Exit with success
exit EXIT_SUCCESS;