aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xacmeman77
-rw-r--r--lib/App/Acmeman/Source/Pound.pm73
2 files changed, 118 insertions, 32 deletions
diff --git a/acmeman b/acmeman
index 1520dcc..5225751 100755
--- a/acmeman
+++ b/acmeman
@@ -295,16 +295,16 @@ matching algorithm. If serving several host names, use the B<Match OR> block.
295After these two steps, your listener section will look like: 295After these two steps, your listener section will look like:
296 296
297 ListenHTTP 297 ListenHTTP
298 Address 0.0.0.0 298 Address 0.0.0.0
299 Port 80 299 Port 80
300 ACME "/var/lib/pound/acme/.well-known/acme-challenge" 300 ACME "/var/lib/pound/acme/.well-known/acme-challenge"
301 Service 301 Service
302 Match OR 302 Match OR
303 Host "www.example.org" 303 Host "www.example.org"
304 Host "example.org" 304 Host "example.org"
305 End 305 End
306 ... 306 ...
307 End 307 End
308 End 308 End
309 309
310=over 4 310=over 4
@@ -823,7 +823,8 @@ from the input files will form the list of its alternative names.
823 823
824 [core] 824 [core]
825 source = pound [--config=FILE] [--host=HOST] \ 825 source = pound [--config=FILE] [--host=HOST] \
826 [--type=http|https] [--listener=NAME] 826 [--type=http|https] [--listener=NAME] \
827 [--comment=TEXT]
827 828
828Domain names will be read from I<FILE> or, if it is not supplied, from 829Domain names will be read from I<FILE> or, if it is not supplied, from
829the default B<pound> configuration file F</etc/pound.cfg>. By default, 830the default B<pound> configuration file F</etc/pound.cfg>. By default,
@@ -841,6 +842,62 @@ appear as arguments to B<Host> statements.
841If B<--listener> option is used, module will scan only the named listener. 842If B<--listener> option is used, module will scan only the named listener.
842To select multiple listeners, use several B<--listener> options. 843To select multiple listeners, use several B<--listener> options.
843 844
845The B<--comment> option defines a text, which, when appearing at the
846start of a comment line, enables host name collection. Such I<pragmatical>
847comments may appear anywhere within listener and service sections and their
848scope is limited by the corresponding section. When this option is used,
849host collection is disabled by default. For example, assuming
850B<--comment=acme>, the following configuration snippet (with irrelevant
851statements replaced by ellipses) will result in issuing certificate for
852C<example.org> and C<www.example.org>:
853
854 ListenerHTTP
855 # acme
856 Service
857 Host -exact "example.org"
858 ...
859 End
860
861 Service
862 Host -exact "www.example.org"
863 ...
864 End
865 End
866
867In contrast, when processing the following snippet, B<acmeman> will issue
868certificate for C<example.org> only:
869
870 ListenerHTTP
871 Service
872 # acme
873 Host -exact "example.org"
874 ...
875 End
876
877 Service
878 Host -exact "www.example.org"
879 ...
880 End
881 End
882
883Furthermore, using B<no-I<TEXT>> at the start of a comment cancels
884the effect of the previous pragmatic comment. This can be used for
885better control of host selection:
886
887 ListenerHTTP
888 Service
889 Match OR
890 # acme
891 Host -exact "example.org"
892 Host -exact "www.example.org"
893 # no-acme
894 Host -exact "test.example.org"
895 End
896 ...
897 End
898 End
899
900
844If the B<--host> (B<-h>) option is used, only one certificate will be 901If the B<--host> (B<-h>) option is used, only one certificate will be
845issued. The I<HOST> will be used as its B<CN>. All the domain names read 902issued. The I<HOST> will be used as its B<CN>. All the domain names read
846from the input files will form the list of its alternative names. 903from the input files will form the list of its alternative names.
@@ -856,9 +913,9 @@ cope with it. When declaring multiple hosts, always use the B<Match OR>
856section, like this: 913section, like this:
857 914
858 Match OR 915 Match OR
859 Host "host1" 916 Host -exact "host1"
860 Host "host2" 917 Host -exact "host2"
861 Host "host3" 918 Host -exact "host3"
862 End 919 End
863 920
864=item 2. These B<Host> statements (or the enclosing B<Match OR> section) 921=item 2. These B<Host> statements (or the enclosing B<Match OR> section)
@@ -967,5 +1024,5 @@ GPLv3+: GNU GPL version 3 or later, see L<http://gnu.org/licenses/gpl.html>
967 1024
968This is free software: you are free to change and redistribute it. 1025This is free software: you are free to change and redistribute it.
969There is NO WARRANTY, to the extent permitted by law. 1026There is NO WARRANTY, to the extent permitted by law.
970 1027
971=cut 1028=cut
diff --git a/lib/App/Acmeman/Source/Pound.pm b/lib/App/Acmeman/Source/Pound.pm
index f02d128..daf5373 100644
--- a/lib/App/Acmeman/Source/Pound.pm
+++ b/lib/App/Acmeman/Source/Pound.pm
@@ -11,16 +11,21 @@ sub new {
11 my $host; 11 my $host;
12 my @listener; 12 my @listener;
13 my @types; 13 my @types;
14 my $comment;
14 GetOptionsFromArray(\@_, 15 GetOptionsFromArray(\@_,
15 'config|f=s' => \$cfgname, 16 'config|f=s' => \$cfgname,
16 'host|h=s' => \$host, 17 'host|h=s' => \$host,
17 'listener=s@' => \@listener, 18 'listener=s@' => \@listener,
18 'type=s@' => \@types 19 'type=s@' => \@types,
20 'comment=s' => \$comment
19 ); 21 );
20 my $self = bless { 22 my $self = bless {
21 cfgname => $cfgname, 23 cfgname => $cfgname,
22 host => $host, 24 host => $host,
23 }, $class; 25 }, $class;
26 if ($comment) {
27 $self->{comment} = qr($comment)
28 }
24 if (@listener) { 29 if (@listener) {
25 $self->{listener} = { map { $_ => 1 } @listener }; 30 $self->{listener} = { map { $_ => 1 } @listener };
26 } 31 }
@@ -89,46 +94,58 @@ sub scan {
89 ST_IGNORE => 5 94 ST_IGNORE => 5
90 }; 95 };
91 my $state = ST_INIT; 96 my $state = ST_INIT;
92 my $acme = 0; 97 my $acme;
93 my $coalesce = 0; 98 my @collect_state;
94 my @lsthosts; 99 my @lsthosts;
95 my @srvhosts; 100 my @srvhosts;
96 my $endcnt; 101 my $endcnt;
97 while (<$fh>) { 102 while (<$fh>) {
98 chomp; 103 chomp;
99 s/#.*//; 104
100 s/^\s+//; 105 s/^\s+//;
106 if ($self->{comment} && m{#\s*(no-)?$self->{comment}}) {
107 if (@collect_state) {
108 my $hint = 1;
109 if ($1) {
110 $hint = 0;
111 }
112 debug(4, "$self->{cfgname}:$.: hint=$hint");
113 $collect_state[$#collect_state] = $hint;
114 }
115 }
116
117 s/#.*//;
101 next if (/^$/); 118 next if (/^$/);
119
102 if ($state == ST_INIT) { 120 if ($state == ST_INIT) {
103 if (/^ListenHTTP(?:(?<s>S)?\s+"(?<name>.*)"\s*)?$/i) { 121 if (/^ListenHTTP(?:(?<s>S)?\s+"(?<name>.*)"\s*)?$/i) {
104 if ($self->lstn_ok($+{s}, $+{name})) { 122 if ($self->lstn_ok($+{s}, $+{name})) {
105 debug(4, "$self->{cfgname}:$.: listener"); 123 debug(4, "$self->{cfgname}:$.: listener");
106 $state = ST_LISTENER; 124 $state = ST_LISTENER;
125 $acme = 0;
107 if (defined($+{s}) && uc($+{s}) eq 'S') { 126 if (defined($+{s}) && uc($+{s}) eq 'S') {
108 $acme = 1; 127 $acme = 1;
109 $coalesce = 1;
110 } 128 }
129 push @collect_state, !defined($self->{comment});
111 @lsthosts = (); 130 @lsthosts = ();
112 } else { 131 } else {
113 $state = ST_IGNORE; 132 $state = ST_IGNORE;
114 } 133 }
115 } 134 }
116 } elsif ($state == ST_LISTENER) { 135 } elsif ($state == ST_LISTENER) {
117 debug(4, "$self->{cfgname}:$.: service");
118 if (/^Service(?:\s+".*"\s*)?$/i) { 136 if (/^Service(?:\s+".*"\s*)?$/i) {
137 debug(4, "$self->{cfgname}:$.: service");
138 push @collect_state, $collect_state[$#collect_state];
119 $state = ST_SERVICE; 139 $state = ST_SERVICE;
120 @srvhosts = (); 140 @srvhosts = ();
121 } elsif (/^ACME\s/i) { 141 } elsif (/^ACME\s/i) {
122 $acme = 1; 142 $acme = 1;
123 } elsif (/^End$/i) { 143 } elsif (/^End$/i) {
124 if ($acme) { 144 debug(4, "$self->{cfgname}:$.: listener ends");
145 pop @collect_state;
146 if ($acme && @lsthosts) {
125 if ($self->{host}) { 147 if ($self->{host}) {
126 $self->define_alias($self->{host}, map { @$_ } @lsthosts); 148 $self->define_alias($self->{host}, map { @$_ } @lsthosts);
127 } elsif ($coalesce) {
128 my @hosts = (map {@$_} @lsthosts);
129 my $cn = shift @hosts;
130 $self->define_domain($cn);
131 $self->define_alias($cn, @hosts) if @hosts;